1use core::marker::PhantomData;
17
18use crate::prelude::*;
19use crate::value_type::{Composite, Primitive, Value, ValueDef, Variant};
20use scale_decode::{FieldIter, TypeResolver};
21
22pub use scale_decode::visitor::DecodeError;
24
25pub type ValueVisitor<Resolver> = DecodeValueVisitor<Resolver, TypeIdContext>;
27
28pub fn decode_value_as_type<R>(
32 data: &mut &[u8],
33 ty_id: R::TypeId,
34 types: &R,
35) -> Result<Value<R::TypeId>, DecodeError>
36where
37 R: TypeResolver,
38 R::TypeId: Clone,
39{
40 scale_decode::visitor::decode_with_visitor(
41 data,
42 ty_id,
43 types,
44 DecodeValueVisitor::<R, TypeIdContext>::new(),
45 )
46}
47
48pub fn decode_composite_as_fields<'resolver, R>(
51 input: &mut &[u8],
52 fields: &mut dyn FieldIter<'resolver, R::TypeId>,
53 types: &'resolver R,
54) -> Result<Composite<R::TypeId>, DecodeError>
55where
56 R: TypeResolver,
57 R::TypeId: Clone,
58{
59 let mut composite = scale_decode::visitor::types::Composite::new(
61 core::iter::empty(),
62 input,
63 fields,
64 types,
65 false,
66 );
67 let val = visit_composite::<R, TypeIdContext>(&mut composite)?;
69 composite.skip_decoding()?;
71 *input = composite.bytes_from_undecoded();
72 Ok(val)
73}
74
75macro_rules! to_unnamed_composite {
77 ($value:ident, $type_id:ident) => {{
78 let mut vals = Vec::with_capacity($value.remaining());
79 while let Some(val) = $value.decode_item(DecodeValueVisitor::<R, F>::new()) {
80 let val = val?;
81 vals.push(val);
82 }
83 Ok(Value {
84 value: ValueDef::Composite(Composite::Unnamed(vals)),
85 context: F::context_from_type_id(&$type_id),
86 })
87 }};
88}
89
90impl scale_decode::DecodeAsFields for Composite<()> {
91 fn decode_as_fields<'resolver, R: TypeResolver>(
92 input: &mut &[u8],
93 fields: &mut dyn FieldIter<'resolver, R::TypeId>,
94 types: &'resolver R,
95 ) -> Result<Self, scale_decode::Error> {
96 let mut composite = scale_decode::visitor::types::Composite::new(
98 core::iter::empty(),
99 input,
100 fields,
101 types,
102 false,
103 );
104 let val = visit_composite::<R, EmptyContext>(&mut composite);
106 composite.skip_decoding()?;
108 *input = composite.bytes_from_undecoded();
109 val.map_err(From::from).map(|v| v.map_context(|_| {}))
110 }
111}
112
113impl scale_decode::DecodeAsFields for Value<()> {
114 fn decode_as_fields<'resolver, R: TypeResolver>(
115 input: &mut &[u8],
116 fields: &mut dyn FieldIter<'resolver, R::TypeId>,
117 types: &'resolver R,
118 ) -> Result<Self, scale_decode::Error> {
119 let composite = Composite::<()>::decode_as_fields(input, fields, types)?;
120 Ok(Value { value: ValueDef::Composite(composite), context: () })
121 }
122}
123
124impl scale_decode::IntoVisitor for Value<()> {
125 type AnyVisitor<R: scale_decode::TypeResolver> =
127 scale_decode::visitor::VisitorWithCrateError<DecodeValueVisitor<R, EmptyContext>>;
128
129 fn into_visitor<R: scale_decode::TypeResolver>() -> Self::AnyVisitor<R> {
130 scale_decode::visitor::VisitorWithCrateError(DecodeValueVisitor::new())
131 }
132}
133
134pub trait ContextFromTypeId<TypeId> {
145 type Output;
146 fn context_from_type_id(type_id: &TypeId) -> Self::Output;
147}
148
149pub struct EmptyContext;
151impl<TypeId> ContextFromTypeId<TypeId> for EmptyContext {
152 type Output = ();
153 fn context_from_type_id(_type_id: &TypeId) {}
154}
155
156pub struct TypeIdContext;
158impl<TypeId: Clone> ContextFromTypeId<TypeId> for TypeIdContext {
159 type Output = TypeId;
160 fn context_from_type_id(type_id: &TypeId) -> TypeId {
161 type_id.clone()
162 }
163}
164
165pub struct DecodeValueVisitor<R: TypeResolver, F> {
167 resolver: PhantomData<(R, F)>,
168}
169impl<R: TypeResolver, F> Default for DecodeValueVisitor<R, F> {
170 fn default() -> Self {
171 Self::new()
172 }
173}
174
175impl<R: TypeResolver, F> DecodeValueVisitor<R, F> {
176 pub fn new() -> Self {
177 DecodeValueVisitor { resolver: PhantomData }
178 }
179}
180
181impl<R, F> scale_decode::visitor::Visitor for DecodeValueVisitor<R, F>
182where
183 R: TypeResolver,
184 F: ContextFromTypeId<R::TypeId>,
185{
186 type Value<'scale, 'info> = Value<F::Output>;
187 type Error = DecodeError;
188 type TypeResolver = R;
189
190 fn visit_bool<'scale, 'info>(
191 self,
192 value: bool,
193 type_id: R::TypeId,
194 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
195 Ok(Value::bool(value).map_context(|_| F::context_from_type_id(&type_id)))
196 }
197 fn visit_char<'scale, 'info>(
198 self,
199 value: char,
200 type_id: R::TypeId,
201 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
202 Ok(Value::char(value).map_context(|_| F::context_from_type_id(&type_id)))
203 }
204 fn visit_u8<'scale, 'info>(
205 self,
206 value: u8,
207 type_id: R::TypeId,
208 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
209 self.visit_u128(value as u128, type_id)
210 }
211 fn visit_u16<'scale, 'info>(
212 self,
213 value: u16,
214 type_id: R::TypeId,
215 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
216 self.visit_u128(value as u128, type_id)
217 }
218 fn visit_u32<'scale, 'info>(
219 self,
220 value: u32,
221 type_id: R::TypeId,
222 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
223 self.visit_u128(value as u128, type_id)
224 }
225 fn visit_u64<'scale, 'info>(
226 self,
227 value: u64,
228 type_id: R::TypeId,
229 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
230 self.visit_u128(value as u128, type_id)
231 }
232 fn visit_u128<'scale, 'info>(
233 self,
234 value: u128,
235 type_id: R::TypeId,
236 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
237 Ok(Value::u128(value).map_context(|_| F::context_from_type_id(&type_id)))
238 }
239 fn visit_u256<'info>(
240 self,
241 value: &[u8; 32],
242 type_id: R::TypeId,
243 ) -> Result<Self::Value<'_, 'info>, Self::Error> {
244 Ok(Value {
245 value: ValueDef::Primitive(Primitive::U256(*value)),
246 context: F::context_from_type_id(&type_id),
247 })
248 }
249 fn visit_i8<'scale, 'info>(
250 self,
251 value: i8,
252 type_id: R::TypeId,
253 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
254 self.visit_i128(value as i128, type_id)
255 }
256 fn visit_i16<'scale, 'info>(
257 self,
258 value: i16,
259 type_id: R::TypeId,
260 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
261 self.visit_i128(value as i128, type_id)
262 }
263 fn visit_i32<'scale, 'info>(
264 self,
265 value: i32,
266 type_id: R::TypeId,
267 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
268 self.visit_i128(value as i128, type_id)
269 }
270 fn visit_i64<'scale, 'info>(
271 self,
272 value: i64,
273 type_id: R::TypeId,
274 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
275 self.visit_i128(value as i128, type_id)
276 }
277 fn visit_i128<'scale, 'info>(
278 self,
279 value: i128,
280 type_id: R::TypeId,
281 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
282 Ok(Value::i128(value).map_context(|_| F::context_from_type_id(&type_id)))
283 }
284 fn visit_i256<'info>(
285 self,
286 value: &[u8; 32],
287 type_id: R::TypeId,
288 ) -> Result<Self::Value<'_, 'info>, Self::Error> {
289 Ok(Value {
290 value: ValueDef::Primitive(Primitive::U256(*value)),
291 context: F::context_from_type_id(&type_id),
292 })
293 }
294 fn visit_sequence<'scale, 'info>(
295 self,
296 value: &mut scale_decode::visitor::types::Sequence<'scale, 'info, R>,
297 type_id: R::TypeId,
298 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
299 to_unnamed_composite!(value, type_id)
300 }
301 fn visit_tuple<'scale, 'info>(
302 self,
303 value: &mut scale_decode::visitor::types::Tuple<'scale, 'info, R>,
304 type_id: R::TypeId,
305 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
306 to_unnamed_composite!(value, type_id)
307 }
308 fn visit_array<'scale, 'info>(
309 self,
310 value: &mut scale_decode::visitor::types::Array<'scale, 'info, R>,
311 type_id: R::TypeId,
312 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
313 to_unnamed_composite!(value, type_id)
314 }
315 fn visit_bitsequence<'scale, 'info>(
316 self,
317 value: &mut scale_decode::visitor::types::BitSequence<'scale>,
318 type_id: R::TypeId,
319 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
320 let bits: Result<_, _> = value.decode()?.collect();
321 Ok(Value {
322 value: ValueDef::BitSequence(bits?),
323 context: F::context_from_type_id(&type_id),
324 })
325 }
326 fn visit_str<'scale, 'info>(
327 self,
328 value: &mut scale_decode::visitor::types::Str<'scale>,
329 type_id: R::TypeId,
330 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
331 Ok(Value::string(value.as_str()?).map_context(|_| F::context_from_type_id(&type_id)))
332 }
333 fn visit_variant<'scale, 'info>(
334 self,
335 value: &mut scale_decode::visitor::types::Variant<'scale, 'info, R>,
336 type_id: R::TypeId,
337 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
338 let values = visit_composite::<R, F>(value.fields())?;
339 Ok(Value {
340 value: ValueDef::Variant(Variant { name: value.name().to_owned(), values }),
341 context: F::context_from_type_id(&type_id),
342 })
343 }
344 fn visit_composite<'scale, 'info>(
345 self,
346 value: &mut scale_decode::visitor::types::Composite<'scale, 'info, R>,
347 type_id: R::TypeId,
348 ) -> Result<Self::Value<'scale, 'info>, Self::Error> {
349 Ok(Value {
350 value: ValueDef::Composite(visit_composite::<R, F>(value)?),
351 context: F::context_from_type_id(&type_id),
352 })
353 }
354}
355
356fn visit_composite<R, F>(
358 value: &mut scale_decode::visitor::types::Composite<'_, '_, R>,
359) -> Result<Composite<F::Output>, DecodeError>
360where
361 R: TypeResolver,
362 F: ContextFromTypeId<R::TypeId>,
363{
364 let len = value.remaining();
365 let named = len > 0 && !value.has_unnamed_fields();
367
368 if named {
369 let mut vals = Vec::with_capacity(len);
370 let mut name = value.peek_name();
371 while let Some(v) = value.decode_item(DecodeValueVisitor::<R, F>::new()) {
372 let v = v?;
373 vals.push((name.expect("all fields should be named; we have checked").to_owned(), v));
374 name = value.peek_name();
376 }
377 Ok(Composite::Named(vals))
378 } else {
379 let mut vals = Vec::with_capacity(len);
380 while let Some(v) = value.decode_item(DecodeValueVisitor::<R, F>::new()) {
381 let v = v?;
382 vals.push(v);
383 }
384 Ok(Composite::Unnamed(vals))
385 }
386}
387
388#[cfg(test)]
389mod test {
390 use super::*;
391 use crate::value;
392 use codec::{Compact, Encode};
393 use scale_info::PortableRegistry;
394
395 fn make_type<T: scale_info::TypeInfo + 'static>() -> (u32, PortableRegistry) {
398 let m = scale_info::MetaType::new::<T>();
399 let mut types = scale_info::Registry::new();
400 let id = types.register_type(&m);
401 let portable_registry: PortableRegistry = types.into();
402
403 (id.id, portable_registry)
404 }
405
406 fn encode_decode_check<T: Encode + scale_info::TypeInfo + 'static>(val: T, exp: Value<()>) {
410 encode_decode_check_explicit_info::<T, _>(val, exp)
411 }
412
413 fn encode_decode_check_explicit_info<Ty: scale_info::TypeInfo + 'static, T: Encode>(
416 val: T,
417 ex: Value<()>,
418 ) {
419 let encoded = val.encode();
420 let encoded = &mut &*encoded;
421
422 let (id, portable_registry) = make_type::<Ty>();
423
424 let val = decode_value_as_type(encoded, id, &portable_registry).expect("decoding failed");
426 assert_eq!(val.remove_context(), ex, "decoded value does not look like what we expected");
428 assert_eq!(encoded.len(), 0, "decoding did not consume all of the encoded bytes");
430 }
431
432 #[test]
433 fn decode_primitives() {
434 encode_decode_check(true, Value::bool(true));
435 encode_decode_check(false, Value::bool(false));
436 encode_decode_check_explicit_info::<char, _>('a' as u32, Value::char('a'));
437 encode_decode_check("hello", Value::string("hello"));
438 encode_decode_check(
439 "hello".to_string(), Value::string("hello"),
441 );
442 encode_decode_check(123u8, Value::u128(123));
443 encode_decode_check(123u16, Value::u128(123));
444 encode_decode_check(123u32, Value::u128(123));
445 encode_decode_check(123u64, Value::u128(123));
446 encode_decode_check(123u128, Value::u128(123));
447 encode_decode_check(123i8, Value::i128(123));
453 encode_decode_check(123i16, Value::i128(123));
454 encode_decode_check(123i32, Value::i128(123));
455 encode_decode_check(123i64, Value::i128(123));
456 encode_decode_check(123i128, Value::i128(123));
457 }
463
464 #[test]
465 fn decode_compact_primitives() {
466 encode_decode_check(Compact(123u8), Value::u128(123));
467 encode_decode_check(Compact(123u16), Value::u128(123));
468 encode_decode_check(Compact(123u32), Value::u128(123));
469 encode_decode_check(Compact(123u64), Value::u128(123));
470 encode_decode_check(Compact(123u128), Value::u128(123));
471 }
472
473 #[test]
474 fn decode_compact_named_wrapper_struct() {
475 #[derive(Encode, scale_info::TypeInfo)]
477 struct MyWrapper {
478 inner: u32,
479 }
480 impl From<Compact<MyWrapper>> for MyWrapper {
481 fn from(val: Compact<MyWrapper>) -> MyWrapper {
482 val.0
483 }
484 }
485 impl codec::CompactAs for MyWrapper {
486 type As = u32;
487
488 fn encode_as(&self) -> &Self::As {
489 &self.inner
490 }
491 fn decode_from(inner: Self::As) -> Result<Self, codec::Error> {
492 Ok(MyWrapper { inner })
493 }
494 }
495
496 encode_decode_check(
497 Compact(MyWrapper { inner: 123 }),
498 Value::named_composite(vec![("inner", Value::u128(123))]),
499 );
500 }
501
502 #[test]
503 fn decode_compact_unnamed_wrapper_struct() {
504 #[derive(Encode, scale_info::TypeInfo)]
506 struct MyWrapper(u32);
507 impl From<Compact<MyWrapper>> for MyWrapper {
508 fn from(val: Compact<MyWrapper>) -> MyWrapper {
509 val.0
510 }
511 }
512 impl codec::CompactAs for MyWrapper {
513 type As = u32;
514
515 fn encode_as(&self) -> &Self::As {
521 &self.0
522 }
523 fn decode_from(inner: Self::As) -> Result<Self, codec::Error> {
524 Ok(MyWrapper(inner))
525 }
526 }
527
528 encode_decode_check(
529 Compact(MyWrapper(123)),
530 Value::unnamed_composite(vec![Value::u128(123)]),
531 );
532 }
533
534 #[test]
535 fn decode_sequence_array_tuple_types() {
536 encode_decode_check(vec![1i32, 2, 3], value!((1, 2, 3)));
537 encode_decode_check(
538 [1i32, 2, 3], Value::unnamed_composite(vec![Value::i128(1), Value::i128(2), Value::i128(3)]),
540 );
541 encode_decode_check(
542 (1i32, true, 123456u128),
543 Value::unnamed_composite(vec![Value::i128(1), Value::bool(true), Value::u128(123456)]),
544 );
545 }
546
547 #[test]
548 fn decode_variant_types() {
549 #[derive(Encode, scale_info::TypeInfo)]
550 enum MyEnum {
551 Foo(bool),
552 Bar { hi: String, other: u128 },
553 }
554
555 encode_decode_check(
556 MyEnum::Foo(true),
557 Value::unnamed_variant("Foo", vec![Value::bool(true)]),
558 );
559 encode_decode_check(
560 MyEnum::Bar { hi: "hello".to_string(), other: 123 },
561 value!(Bar { hi: "hello", other: 123u32 }),
562 );
563 }
564
565 #[test]
566 fn decode_composite_types() {
567 #[derive(Encode, scale_info::TypeInfo)]
568 struct Unnamed(bool, String, Vec<u8>);
569
570 #[derive(Encode, scale_info::TypeInfo)]
571 struct Named {
572 is_valid: bool,
573 name: String,
574 bytes: Vec<u8>,
575 }
576
577 encode_decode_check(
578 Unnamed(true, "James".into(), vec![1, 2, 3]),
579 value!((true, "James", (1u8, 2u8, 3u8))),
580 );
581 encode_decode_check(
582 Named { is_valid: true, name: "James".into(), bytes: vec![1, 2, 3] },
583 value!({is_valid: true, name: "James", bytes: (1u8, 2u8, 3u8)}),
584 );
585 }
586
587 #[test]
588 fn decoding_zero_length_composites_always_unnamed() {
589 #[derive(Encode, scale_info::TypeInfo)]
592 struct Named {}
593 #[derive(Encode, scale_info::TypeInfo)]
594 struct Unnamed();
595
596 encode_decode_check(Unnamed(), Value::unnamed_composite(vec![]));
597 encode_decode_check(Named {}, Value::unnamed_composite(vec![]));
598 }
599
600 #[test]
601 fn decode_bit_sequence() {
602 use scale_bits::bits;
603
604 encode_decode_check(bits![0, 1, 1, 0, 1, 0], Value::bit_sequence(bits![0, 1, 1, 0, 1, 0]));
606 }
607
608 #[test]
609 fn decode_composite_fields() {
610 use codec::Encode;
611 use scale_decode::DecodeAsFields;
612
613 #[derive(Encode, scale_decode::DecodeAsType, scale_info::TypeInfo)]
614 struct Foo {
615 a: String,
616 b: bool,
617 c: u16,
618 }
619
620 let (id, types) = make_type::<Foo>();
622 let scale_info::TypeDef::Composite(c) = &types.resolve(id).unwrap().type_def else {
623 panic!("Couldn't get fields");
624 };
625 let mut fields = c.fields.iter().map(|f| scale_decode::Field::new(f.ty.id, f.name));
626
627 let foo = Foo { a: "Hello".to_owned(), b: true, c: 123 };
629 let foo_bytes = foo.encode();
630 let foo_bytes_cursor = &mut &*foo_bytes;
631
632 let out = Composite::decode_as_fields(foo_bytes_cursor, &mut fields, &types)
634 .expect("can decode as fields")
635 .map_context(|_| ());
636 assert_eq!(
637 out,
638 Composite::named([
639 ("a", Value::string("Hello")),
640 ("b", Value::bool(true)),
641 ("c", Value::u128(123))
642 ])
643 );
644 assert_eq!(foo_bytes_cursor.len(), 0, "all bytes should have been consumed");
645 }
646}