scale_decode/impls/
mod.rs

1// Copyright (C) 2023 Parity Technologies (UK) Ltd. (admin@parity.io)
2// This file is a part of the scale-decode crate.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//         http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#[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
53/// Generate an [`IntoVisitor`] impl for basic types `T` where `BasicVisitor<T>` impls `Visitor`.
54macro_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
67/// Ignore single-field tuples/composites and visit the single field inside instead.
68macro_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
191// Generate impls to encode things based on some other type. We do this by implementing
192// `IntoVisitor` and using the `AndThen` combinator to map from an existing one to the desired output.
193macro_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                // Use the source visitor to decode into some type:
212                let inner_res = decode_with_visitor(input, type_id, types, <$source>::into_visitor());
213                // map this type into our desired output and return it:
214                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
230// A custom implementation for `Cow` because it's rather tricky; the visitor we want is whatever the
231// `ToOwned` value for the Cow is, and Cow's have specific constraints, too.
232impl<'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        // Use the ToOwned visitor to decode into some type:
249        let inner_res =
250            decode_with_visitor(input, type_id, types, <<T as ToOwned>::Owned>::into_visitor());
251        // map this type into our owned Cow to return:
252        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
305// For arrays of fixed lengths, we decode to a vec first and then try to turn that into the fixed size array.
306// Like vecs, we can decode from tuples, sequences or arrays if the types line up ok.
307macro_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            // Get the name. If no name, skip over the corresponding value.
359            let Some(key) = value.peek_name() else {
360                value.decode_item(crate::visitor::IgnoreVisitor::<R>::new()).transpose()?;
361                continue;
362            };
363            // Decode the value now that we have a valid name.
364            let Some(val) = value.decode_item(T::into_visitor::<R>()) else { break };
365            // Save to the map.
366            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
447// Impl Visitor/DecodeAsType for all primitive number types
448macro_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
519// Decode tuple types from any matching type.
520macro_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            // Match on the resolved kind; try to decode as inner type if it's not a
561            // composite, tuple, or a type ID we can't find. Else fall back to default.
562            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 error decoding, or false, just fall back to default behaviour and don't try to decode as inner.
579            if let Err(_) | Ok(false) =
580                types.resolve_type(type_id.clone(), TryDecodeAsInner(PhantomData))
581            {
582                return DecodeAsTypeResult::Skipped(self);
583            }
584
585            // Else, try to decode as the inner type.
586            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        /* nothing */
593    };
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            // If we're trying to decode to a 1-tuple, and the type we're decoding
607            // isn't a tuple or composite, then decode the inner type and add the tuple.
608            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        // We can turn this tuple into a visitor which knows how to decode it:
627        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        // We can decode given a list of fields (just delegate to the visitor impl:
637        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                // [jsdw] TODO: Passing a "default type ID" to a visitor just to satisfy the signature is
644                // a bit hideous (and requires `TypeId: Default`). Can we re-work this to avoid?
645                let val = <($($t,)*)>::into_visitor().visit_composite(&mut composite, Default::default());
646
647                // Skip over bytes that we decoded:
648                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);
678// ^ Note: We make sure to support as many as parity-scale-codec's impls do.
679
680/// This takes anything that can decode a stream if items and return an iterator over them.
681fn 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    /// Given a type definition, return type ID and registry representing it.
705    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    // For most of our tests, we'll assert that whatever type we encode, we can decode back again to the given type.
715    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    // Normally, the type info we want to use comes along with the type we're encoding.
729    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    // Most of the time we'll just make sure that we can encode and decode back to the same type.
738    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    // Most of the time we'll just make sure that we can encode and decode back to the same type.
747    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    // Test that something can be encoded and then DecodeAsFields will work to decode it again.
755    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        // Decoding a Cow means being able to jump into the inner composite type
844        // (Cow's are a one-field composite type in TypeInfo by the looks of it).
845        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        // assert_encode_decode_to(&vec![1u8,2,3], &BinaryHeap::from_iter([1u8,2,3])); // No partialEq for BinaryHeap
856    }
857
858    #[test]
859    fn decode_types_via_tuples_or_composites() {
860        // Some type we know will be a composite type because we made it..
861        #[derive(DecodeAsType, codec::Encode, scale_info::TypeInfo)]
862        #[decode_as_type(crate_path = "crate")]
863        struct Foo<A> {
864            val: A,
865        }
866
867        // Make our own enum just to check that it can be decoded through tuples etc too:
868        #[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        // All of these types can be decoded through nested
892        // tuples or composite types that have exactly one field.
893        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        // Some struct with the same shape as our tuples.
917        #[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        // Decode to the same:
926        assert_encode_decode(&(1u8, 2u16, true));
927        // Decode to struct of similar shape:
928        assert_encode_decode_to(&(1u8, 2u8, true), &Foo { a: 1u8, b: 2u16, c: true });
929        // Decode from struct of similar shape:
930        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        // Same:
943        assert_encode_decode_to(&input, &(true, (1u8, 3u32)));
944        // Different:
945        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        // These are hardcoded so let's make sure they work..
956        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                // fields will be defaulted if skipped:
1024                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, // fields will be defaulted if skipped:
1045                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                // the codec attr should work too:
1060                #[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        // Tuples should work, too:
1114        assert_encode_decode_as_fields((true, 123u8, "hello".to_string()));
1115    }
1116}