1use alloc::format;
17use alloc::vec::Vec;
18use scale_decode::DecodeAsType;
19use scale_type_resolver::TypeResolver;
20
21pub trait IntoDecodableValues: Sized {
26 type Values: DecodableValues<Target = Self>;
28
29 fn into_decodable_values() -> Self::Values;
32
33 fn num_decodable_values() -> Option<usize>;
39}
40
41pub trait DecodableValues {
44 type Target;
46
47 fn decode_next_value<Resolver>(
57 &mut self,
58 input: &mut &[u8],
59 type_id: Resolver::TypeId,
60 types: &Resolver,
61 ) -> Result<(), scale_decode::Error>
62 where
63 Resolver: TypeResolver;
64
65 fn decoded_target(self) -> Self::Target;
72}
73
74impl<T: DecodeAsType> IntoDecodableValues for Vec<T> {
76 type Values = Self;
77 fn into_decodable_values() -> Self::Values {
78 Vec::new()
79 }
80 fn num_decodable_values() -> Option<usize> {
81 None
82 }
83}
84
85impl<T: DecodeAsType> DecodableValues for Vec<T> {
86 type Target = Self;
87
88 fn decode_next_value<Resolver>(
89 &mut self,
90 input: &mut &[u8],
91 type_id: Resolver::TypeId,
92 types: &Resolver,
93 ) -> Result<(), scale_decode::Error>
94 where
95 Resolver: TypeResolver,
96 {
97 let item = T::decode_as_type(input, type_id, types)?;
98 self.push(item);
99 Ok(())
100 }
101
102 fn decoded_target(self) -> Self::Target {
103 self
104 }
105}
106
107impl<const N: usize, T: DecodeAsType> IntoDecodableValues for [T; N] {
109 type Values = DecodeArrayAsTypes<N, T>;
110 fn into_decodable_values() -> Self::Values {
111 DecodeArrayAsTypes {
112 items: [const { None }; N],
113 next_idx: 0,
114 }
115 }
116 fn num_decodable_values() -> Option<usize> {
117 Some(N)
118 }
119}
120
121pub struct DecodeArrayAsTypes<const N: usize, T> {
122 items: [Option<T>; N],
123 next_idx: usize,
124}
125
126impl<const N: usize, T: DecodeAsType> DecodableValues for DecodeArrayAsTypes<N, T> {
127 type Target = [T; N];
128
129 fn decode_next_value<Resolver>(
130 &mut self,
131 input: &mut &[u8],
132 type_id: Resolver::TypeId,
133 types: &Resolver,
134 ) -> Result<(), scale_decode::Error>
135 where
136 Resolver: TypeResolver,
137 {
138 if self.next_idx >= N {
139 let e = format!(
140 "decode_next_value called too many times (expected {N} calls) to decode [{}; N]",
141 core::any::type_name::<T>()
142 );
143 return Err(scale_decode::Error::custom_string(e));
144 }
145
146 let item = T::decode_as_type(input, type_id, types)?;
147
148 self.items[self.next_idx] = Some(item);
149 self.next_idx += 1;
150 Ok(())
151 }
152 fn decoded_target(self) -> Self::Target {
153 if self.next_idx != N {
154 panic!(
155 "decode_next_value was not called enough times (expected {N} calls, got {} calls) to decode [{}; N]",
156 self.next_idx,
157 core::any::type_name::<T>()
158 )
159 }
160
161 let mut items = self.items;
163 core::array::from_fn(|idx| {
164 items[idx]
165 .take()
166 .expect("Item should be present in DecodeArrayAsType array")
167 })
168 }
169}
170
171impl IntoDecodableValues for () {
173 type Values = ();
174 fn into_decodable_values() -> Self::Values {}
175 fn num_decodable_values() -> Option<usize> {
176 Some(0)
177 }
178}
179
180impl DecodableValues for () {
181 type Target = ();
182
183 fn decode_next_value<Resolver>(
184 &mut self,
185 _input: &mut &[u8],
186 _type_id: Resolver::TypeId,
187 _types: &Resolver,
188 ) -> Result<(), scale_decode::Error>
189 where
190 Resolver: TypeResolver,
191 {
192 Err(scale_decode::Error::custom_str(
193 "decode_next_value cannot be called on an empty tuple",
194 ))
195 }
196
197 fn decoded_target(self) -> Self::Target {}
198}
199
200macro_rules! impl_tuple_decodable {
202 ($($ty:ident $number:tt),*) => {
203 const _: () = {
204 const TUPLE_LEN: usize = 0 $(+ $number - $number + 1)*;
205
206 impl <$($ty: scale_decode::DecodeAsType),*> IntoDecodableValues for ($($ty,)*) {
207 type Values = TupleIter<$($ty),*>;
208 fn into_decodable_values() -> Self::Values {
209 TupleIter {
210 idx: 0,
211 items: ($(Option::<$ty>::None,)*),
212 }
213 }
214 fn num_decodable_values() -> Option<usize> {
215 Some(TUPLE_LEN)
216 }
217 }
218
219 pub struct TupleIter<$($ty),*> {
220 idx: usize,
221 items: ($(Option<$ty>,)*)
222 }
223
224 impl <$($ty: scale_decode::DecodeAsType),*> DecodableValues for TupleIter<$($ty),*> {
225 type Target = ($($ty,)*);
226
227 fn decode_next_value<Resolver>(
228 &mut self,
229 input: &mut &[u8],
230 type_id: Resolver::TypeId,
231 types: &Resolver,
232 ) -> Result<(), scale_decode::Error>
233 where
234 Resolver: TypeResolver,
235 {
236 $(
237 if self.idx == $number {
238 let item = $ty::decode_as_type(input, type_id, types)?;
239 self.items.$number = Some(item);
240 self.idx += 1;
241 return Ok(());
242 }
243 )*
244 Err(scale_decode::Error::custom_str("decode_next_value called but no more tuple entries to decode"))
245 }
246 fn decoded_target(self) -> Self::Target {
247 if self.idx != TUPLE_LEN {
248 panic!(
249 "decode_next_value not called enough times (expected {TUPLE_LEN} calls, got {} calls) to decode {}",
250 self.idx,
251 core::any::type_name::<Self::Target>()
252 )
253 }
254
255 (
256 $(
257 self.items.$number.unwrap(),
258 )*
259 )
260 }
261 }
262 };
263 };
264}
265
266impl_tuple_decodable!(A 0);
267impl_tuple_decodable!(A 0, B 1);
268impl_tuple_decodable!(A 0, B 1, C 2);
269impl_tuple_decodable!(A 0, B 1, C 2, D 3);
270impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4);
271impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4, F 5);
272impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
273impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
274impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
275impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
276impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
277impl_tuple_decodable!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11);
278
279#[cfg(test)]
280mod test {
281 use super::*;
282 use parity_scale_codec::Encode;
283 use scale_info_legacy::LookupName;
284
285 fn ln(ty: &str) -> LookupName {
286 LookupName::parse(ty).unwrap()
287 }
288
289 #[test]
290 fn test_decode_empty_tuple() {
291 let types = crate::legacy_types::polkadot::relay_chain();
293 let types = types.for_spec_version(0);
294
295 let n = <()>::num_decodable_values();
296 assert_eq!(n, Some(0));
297
298 #[allow(clippy::let_unit_value)]
301 let mut decodable = <()>::into_decodable_values();
302
303 decodable
305 .decode_next_value(&mut &*true.encode(), ln("bool"), &types)
306 .unwrap_err();
307
308 let () = decodable.decoded_target();
310 }
311
312 #[test]
313 fn test_tuple_decodable_values() {
314 let types = crate::legacy_types::polkadot::relay_chain();
316 let types = types.for_spec_version(0);
317
318 let n = <(bool, String, u64)>::num_decodable_values();
319 assert_eq!(n, Some(3));
320
321 let mut decodable = <(bool, String, u64)>::into_decodable_values();
322
323 decodable
324 .decode_next_value(&mut &*true.encode(), ln("bool"), &types)
325 .unwrap();
326 decodable
327 .decode_next_value(&mut &*"hello".encode(), ln("String"), &types)
328 .unwrap();
329 decodable
330 .decode_next_value(&mut &*123u8.encode(), ln("u8"), &types)
331 .unwrap();
332
333 decodable
335 .decode_next_value(&mut &*true.encode(), ln("bool"), &types)
336 .unwrap_err();
337
338 assert_eq!(
339 decodable.decoded_target(),
340 (true, String::from("hello"), 123u64)
341 );
342 }
343
344 #[test]
345 fn test_decode_empty_array() {
346 let types = crate::legacy_types::polkadot::relay_chain();
348 let types = types.for_spec_version(0);
349
350 let n = <[u64; 0]>::num_decodable_values();
351 assert_eq!(n, Some(0));
352
353 let mut decodable = <[u64; 0]>::into_decodable_values();
354
355 decodable
357 .decode_next_value(&mut &*1u32.encode(), ln("u32"), &types)
358 .unwrap_err();
359
360 assert_eq!(decodable.decoded_target(), [] as [u64; 0]);
361 }
362
363 #[test]
364 fn test_decodable_array() {
365 let types = crate::legacy_types::polkadot::relay_chain();
367 let types = types.for_spec_version(0);
368
369 let n = <[u64; 3]>::num_decodable_values();
370 assert_eq!(n, Some(3));
371
372 let mut decodable = <[u64; 3]>::into_decodable_values();
373
374 decodable
375 .decode_next_value(&mut &*1u8.encode(), ln("u8"), &types)
376 .unwrap();
377 decodable
378 .decode_next_value(&mut &*2u16.encode(), ln("u16"), &types)
379 .unwrap();
380 decodable
381 .decode_next_value(&mut &*3u32.encode(), ln("u32"), &types)
382 .unwrap();
383
384 decodable
386 .decode_next_value(&mut &*4u32.encode(), ln("u32"), &types)
387 .unwrap_err();
388
389 assert_eq!(decodable.decoded_target(), [1u64, 2u64, 3u64]);
390 }
391}