1use crate::prelude::*;
17use crate::value_type::{Composite, Primitive, Value, ValueDef, Variant};
18use codec::{Compact, Encode};
19use scale_bits::Bits;
20use scale_decode::TypeResolver;
21use scale_encode::error::ErrorKind;
22use scale_encode::{error::Kind, EncodeAsFields, EncodeAsType, Error};
23use scale_encode::{
24 Composite as EncodeComposite, CompositeField, FieldIter, Variant as EncodeVariant,
25};
26
27impl<T> EncodeAsType for Value<T> {
28 fn encode_as_type_to<R: TypeResolver>(
29 &self,
30 type_id: R::TypeId,
31 types: &R,
32 out: &mut Vec<u8>,
33 ) -> Result<(), Error> {
34 match &self.value {
35 ValueDef::Composite(val) => encode_composite(val, type_id, types, out),
36 ValueDef::Variant(val) => encode_variant(val, type_id, types, out),
37 ValueDef::Primitive(val) => encode_primitive(val, type_id, types, out),
38 ValueDef::BitSequence(val) => encode_bitsequence(val, type_id, types, out),
39 }
40 }
41}
42
43impl<T> EncodeAsFields for Value<T> {
44 fn encode_as_fields_to<R: TypeResolver>(
45 &self,
46 fields: &mut dyn FieldIter<'_, R::TypeId>,
47 types: &R,
48 out: &mut Vec<u8>,
49 ) -> Result<(), Error> {
50 match &self.value {
51 ValueDef::Composite(composite) => composite.encode_as_fields_to(fields, types, out),
52 _ => Err(Error::custom_str("Cannot encode non-composite Value shape into fields")),
53 }
54 }
55}
56
57impl<T> EncodeAsFields for Composite<T> {
58 fn encode_as_fields_to<R: TypeResolver>(
59 &self,
60 fields: &mut dyn FieldIter<'_, R::TypeId>,
61 types: &R,
62 out: &mut Vec<u8>,
63 ) -> Result<(), Error> {
64 match self {
65 Composite::Named(vals) => {
66 let keyvals =
67 vals.iter().map(|(key, val)| (Some(&**key), CompositeField::new(val)));
68 EncodeComposite::new(keyvals).encode_composite_fields_to(fields, types, out)
69 }
70 Composite::Unnamed(vals) => {
71 let vals = vals.iter().map(|val| (None, CompositeField::new(val)));
72 EncodeComposite::new(vals).encode_composite_fields_to(fields, types, out)
73 }
74 }
75 }
76}
77
78fn encode_composite<T, R: TypeResolver>(
83 value: &Composite<T>,
84 mut type_id: R::TypeId,
85 types: &R,
86 out: &mut Vec<u8>,
87) -> Result<(), Error> {
88 fn do_encode_composite<T, R: TypeResolver>(
91 value: &Composite<T>,
92 type_id: R::TypeId,
93 types: &R,
94 out: &mut Vec<u8>,
95 ) -> Result<(), Error> {
96 let ctx = (type_id.clone(), out);
98
99 let visit_composite_or_tuple =
100 |(type_id, out): (R::TypeId, &mut Vec<u8>)| -> Result<(), Error> {
101 match value {
102 Composite::Named(vals) => {
103 let keyvals =
104 vals.iter().map(|(key, val)| (Some(&**key), CompositeField::new(val)));
105 EncodeComposite::new(keyvals)
106 .encode_composite_as_type_to(type_id, types, out)
107 }
108 Composite::Unnamed(vals) => {
109 let vals = vals.iter().map(|val| (None, CompositeField::new(val)));
110 EncodeComposite::new(vals).encode_composite_as_type_to(type_id, types, out)
111 }
112 }
113 };
114
115 let visitor = scale_type_resolver::visitor::new::<
116 '_,
117 (R::TypeId, &mut Vec<u8>),
118 R::TypeId,
119 Result<(), Error>,
120 _,
121 >(ctx, |(type_id, out), _| {
122 let mut values = value.values();
123 match (values.next(), values.next()) {
124 (Some(value), None) => value.encode_as_type_to(type_id, types, out),
126 _ => Err(Error::new(ErrorKind::WrongShape {
128 actual: Kind::Tuple,
129 expected_id: format!("{:?}", type_id),
130 })),
131 }
132 })
133 .visit_composite(|ctx, _, _| visit_composite_or_tuple(ctx))
134 .visit_tuple(|ctx, _| visit_composite_or_tuple(ctx))
135 .visit_sequence(|(_, out), _path, type_id| {
136 Compact(value.len() as u32).encode_to(out);
138 match value {
139 Composite::Named(named_vals) => {
140 for (name, val) in named_vals {
141 val.encode_as_type_to(type_id.clone(), types, out)
142 .map_err(|e| e.at_field(name.to_string()))?;
143 }
144 }
145 Composite::Unnamed(vals) => {
146 for (idx, val) in vals.iter().enumerate() {
147 val.encode_as_type_to(type_id.clone(), types, out)
148 .map_err(|e| e.at_idx(idx))?;
149 }
150 }
151 }
152 Ok(())
153 })
154 .visit_array(|(_, out), type_id, array_len| {
155 if value.len() != array_len {
156 return Err(Error::new(ErrorKind::WrongLength {
157 actual_len: value.len(),
158 expected_len: array_len,
159 }));
160 }
161 for (idx, val) in value.values().enumerate() {
162 val.encode_as_type_to(type_id.clone(), types, out).map_err(|e| e.at_idx(idx))?;
163 }
164 Ok(())
165 })
166 .visit_bit_sequence(|(_, out), store, order| {
167 let format = scale_bits::Format { store, order };
168 encode_vals_to_bitsequence(value.values(), out, format)
169 });
170
171 match types.resolve_type(type_id, visitor) {
172 Ok(Ok(())) => Ok(()),
173 Ok(Err(err)) => Err(err),
174 Err(err) => Err(Error::new(ErrorKind::TypeResolvingError(format!("{:?}", err)))),
175 }
176 }
177
178 let original_error = {
183 let mut temp_out = Vec::new();
184 match do_encode_composite(value, type_id.clone(), types, &mut temp_out) {
185 Ok(()) => {
186 out.extend_from_slice(&temp_out);
187 return Ok(());
188 }
189 Err(e) => e,
190 }
191 };
192
193 {
198 let (inner_type_id, inner_is_different) =
199 find_single_entry_with_same_repr::<R>(type_id.clone(), types);
200 if inner_is_different {
201 let mut temp_out = Vec::new();
202 if let Ok(()) = do_encode_composite(value, inner_type_id.clone(), types, &mut temp_out)
203 {
204 out.extend_from_slice(&temp_out);
205 return Ok(());
206 }
207 type_id = inner_type_id;
208 }
209 }
210
211 if let Some(value) = get_only_value_from_composite(value) {
217 let mut temp_out = Vec::new();
218 if let Ok(()) = value.encode_as_type_to(type_id.clone(), types, &mut temp_out) {
219 out.extend_from_slice(&temp_out);
220 return Ok(());
221 }
222 }
223
224 Err(original_error)
226}
227
228fn find_single_entry_with_same_repr<R: TypeResolver>(
232 type_id: R::TypeId,
233 types: &R,
234) -> (R::TypeId, bool) {
235 fn do_find<R: TypeResolver>(
236 type_id: R::TypeId,
237 types: &R,
238 type_id_has_changed: bool,
239 ) -> (R::TypeId, bool) {
240 let ctx = (type_id.clone(), type_id_has_changed);
241 let visitor = scale_type_resolver::visitor::new(ctx.clone(), |ctx, _| ctx)
242 .visit_tuple(|return_unchanged, fields| {
243 if fields.len() == 1 {
244 let ty = fields.next().expect("has 1 item; qed;");
245 do_find(ty, types, true)
246 } else {
247 return_unchanged
248 }
249 })
250 .visit_composite(|return_unchanged, _, fields| {
251 if fields.len() == 1 {
252 let ty = fields.next().expect("has 1 item; qed;").id;
253 do_find(ty, types, true)
254 } else {
255 return_unchanged
256 }
257 })
258 .visit_array(
259 |return_unchanged, ty_id, len| {
260 if len == 1 {
261 do_find(ty_id, types, true)
262 } else {
263 return_unchanged
264 }
265 },
266 );
267 types.resolve_type(type_id, visitor).unwrap_or(ctx)
268 }
269 do_find(type_id, types, false)
270}
271
272fn get_only_value_from_composite<T>(value: &'_ Composite<T>) -> Option<&'_ Value<T>> {
274 let mut values = value.values();
275 match (values.next(), values.next()) {
276 (Some(value), None) => Some(value),
277 _ => None,
278 }
279}
280
281fn encode_vals_to_bitsequence<'a, T: 'a>(
284 vals: impl ExactSizeIterator<Item = &'a Value<T>>,
285 out: &mut Vec<u8>,
286 format: scale_bits::Format,
287) -> Result<(), Error> {
288 let mut bools = Vec::with_capacity(vals.len());
289 for (idx, value) in vals.enumerate() {
290 if let Some(v) = value.as_bool() {
291 bools.push(v);
293 } else if let Some(v) = value.as_u128() {
294 if v == 0 || v == 1 {
296 bools.push(v == 1)
297 } else {
298 return Err(Error::custom_str(
299 "Cannot encode non-boolean/0/1 value into a bit sequence entry",
300 )
301 .at_idx(idx));
302 }
303 } else if let Some(v) = value.as_i128() {
304 if v == 0 || v == 1 {
306 bools.push(v == 1)
307 } else {
308 return Err(Error::custom_str(
309 "Cannot encode non-boolean/0/1 value into a bit sequence entry",
310 )
311 .at_idx(idx));
312 }
313 } else {
314 return Err(Error::custom_str(
316 "Cannot encode non-boolean/0/1 value into a bit sequence entry",
317 )
318 .at_idx(idx));
319 }
320 }
321
322 scale_bits::encode_using_format_to(bools.into_iter(), format, out);
323 Ok(())
324}
325
326fn encode_variant<T, R: TypeResolver>(
327 value: &Variant<T>,
328 type_id: R::TypeId,
329 types: &R,
330 out: &mut Vec<u8>,
331) -> Result<(), Error> {
332 match &value.values {
333 Composite::Named(vals) => {
334 let keyvals = vals.iter().map(|(key, val)| (Some(&**key), CompositeField::new(val)));
335 EncodeVariant { name: &value.name, fields: EncodeComposite::new(keyvals) }
336 .encode_variant_as_type_to(type_id, types, out)
337 }
338 Composite::Unnamed(vals) => {
339 let vals = vals.iter().map(|val| (None, CompositeField::new(val)));
340 EncodeVariant { name: &value.name, fields: EncodeComposite::new(vals) }
341 .encode_variant_as_type_to(type_id, types, out)
342 }
343 }
344}
345
346fn encode_primitive<R: TypeResolver>(
347 value: &Primitive,
348 type_id: R::TypeId,
349 types: &R,
350 bytes: &mut Vec<u8>,
351) -> Result<(), Error> {
352 match value {
353 Primitive::Bool(val) => val.encode_as_type_to(type_id, types, bytes),
354 Primitive::Char(val) => val.encode_as_type_to(type_id, types, bytes),
355 Primitive::String(val) => val.encode_as_type_to(type_id, types, bytes),
356 Primitive::U128(val) => val.encode_as_type_to(type_id, types, bytes),
357 Primitive::I128(val) => val.encode_as_type_to(type_id, types, bytes),
358 Primitive::U256(val) => val.encode_as_type_to(type_id, types, bytes),
359 Primitive::I256(val) => val.encode_as_type_to(type_id, types, bytes),
360 }
361}
362
363fn encode_bitsequence<R: TypeResolver>(
364 value: &Bits,
365 type_id: R::TypeId,
366 types: &R,
367 bytes: &mut Vec<u8>,
368) -> Result<(), Error> {
369 value.encode_as_type_to(type_id, types, bytes)
370}
371
372#[cfg(test)]
373mod test {
374 use super::*;
375 use crate::value;
376 use codec::{Compact, Encode};
377 use scale_info::PortableRegistry;
378
379 #[cfg(feature = "__std")]
381 fn panic_after<T, F>(d: core::time::Duration, f: F) -> T
382 where
383 T: Send + 'static,
384 F: FnOnce() -> T,
385 F: Send + 'static,
386 {
387 use std::{sync::mpsc, thread};
388
389 let (done_tx, done_rx) = mpsc::channel();
390 let handle = thread::spawn(move || {
391 let val = f();
392 done_tx.send(()).expect("Unable to send completion signal");
393 val
394 });
395
396 match done_rx.recv_timeout(d) {
397 Ok(_) => handle.join().expect("Thread panicked"),
398 Err(_) => panic!("Thread took too long"),
399 }
400 }
401
402 fn make_type<T: scale_info::TypeInfo + 'static>() -> (u32, PortableRegistry) {
405 let m = scale_info::MetaType::new::<T>();
406 let mut types = scale_info::Registry::new();
407 let id = types.register_type(&m);
408 let portable_registry: PortableRegistry = types.into();
409
410 (id.id, portable_registry)
411 }
412
413 fn assert_can_encode_to_type<T: Encode + scale_info::TypeInfo + 'static>(
415 value: Value<()>,
416 ty: T,
417 ) {
418 let expected = ty.encode();
419 let mut buf = Vec::new();
420
421 let (ty_id, types) = make_type::<T>();
422
423 value.encode_as_type_to(ty_id, &types, &mut buf).expect("error encoding value as type");
424 assert_eq!(expected, buf);
425 }
426
427 #[test]
428 fn can_encode_basic_primitive_values() {
429 assert_can_encode_to_type(Value::i128(123), 123i8);
430 assert_can_encode_to_type(Value::i128(123), 123i16);
431 assert_can_encode_to_type(Value::i128(123), 123i32);
432 assert_can_encode_to_type(Value::i128(123), 123i64);
433 assert_can_encode_to_type(Value::i128(123), 123i128);
434
435 assert_can_encode_to_type(Value::u128(123), 123u8);
436 assert_can_encode_to_type(Value::u128(123), 123u16);
437 assert_can_encode_to_type(Value::u128(123), 123u32);
438 assert_can_encode_to_type(Value::u128(123), 123u64);
439 assert_can_encode_to_type(Value::u128(123), 123u128);
440
441 assert_can_encode_to_type(Value::bool(true), true);
442 assert_can_encode_to_type(Value::bool(false), false);
443
444 assert_can_encode_to_type(Value::string("Hello"), "Hello");
445 assert_can_encode_to_type(Value::string("Hello"), "Hello".to_string());
446 }
447
448 #[test]
449 fn chars_encoded_like_numbers() {
450 assert_can_encode_to_type(Value::char('j'), 'j' as u32);
451 assert_can_encode_to_type(Value::char('j'), b'j');
452 }
453
454 #[test]
455 fn can_encode_primitive_arrs_to_array() {
456 use crate::Primitive;
457
458 assert_can_encode_to_type(Value::primitive(Primitive::U256([12u8; 32])), [12u8; 32]);
459 assert_can_encode_to_type(Value::primitive(Primitive::I256([12u8; 32])), [12u8; 32]);
460 }
461
462 #[test]
463 fn can_encode_primitive_arrs_to_vecs() {
464 use crate::Primitive;
465
466 assert_can_encode_to_type(Value::primitive(Primitive::U256([12u8; 32])), vec![12u8; 32]);
467 assert_can_encode_to_type(Value::primitive(Primitive::I256([12u8; 32])), vec![12u8; 32]);
468 }
469
470 #[test]
471 fn can_encode_arrays() {
472 let value = Value::unnamed_composite(vec![
473 Value::u128(1),
474 Value::u128(2),
475 Value::u128(3),
476 Value::u128(4),
477 ]);
478 assert_can_encode_to_type(value, [1u16, 2, 3, 4]);
479 }
480
481 #[test]
482 fn can_encode_variants() {
483 #[derive(Encode, scale_info::TypeInfo)]
484 enum Foo {
485 Named { hello: String, foo: bool },
486 Unnamed(u64, Vec<bool>),
487 }
488
489 let named_value = value!(Named { foo: true, hello: "world" });
490
491 assert_can_encode_to_type(named_value, Foo::Named { hello: "world".into(), foo: true });
492
493 let unnamed_value = value!(Unnamed(123u64, (true, false, true)));
494
495 assert_can_encode_to_type(unnamed_value, Foo::Unnamed(123, vec![true, false, true]));
496 }
497
498 #[test]
499 fn can_encode_vec_tuples() {
500 let vec_tuple = value!(((20u8, 30u16)));
502
503 assert_can_encode_to_type(vec_tuple, vec![(20u8, 30u16)]);
504 }
505
506 #[test]
507 fn can_encode_structs() {
508 #[derive(Encode, scale_info::TypeInfo)]
509 struct Foo {
510 hello: String,
511 foo: bool,
512 }
513
514 let named_value = value!({foo: true, hello: "world"});
515
516 assert_can_encode_to_type(named_value, Foo { hello: "world".into(), foo: true });
517 }
518
519 #[test]
520 fn can_encode_tuples_from_named_composite() {
521 let named_value = value!({hello: "world", foo: true});
522 assert_can_encode_to_type(named_value, ("world", true));
523 }
524
525 #[test]
526 fn can_encode_tuples_from_unnamed_composite() {
527 let unnamed_value = value!(("world", true));
528 assert_can_encode_to_type(unnamed_value, ("world", true));
529 }
530
531 #[test]
532 fn can_encode_unnamed_composite_to_named_struct() {
533 #[derive(Encode, scale_info::TypeInfo)]
534 struct Foo {
535 hello: String,
536 foo: bool,
537 }
538
539 let unnamed_value = value!(("world", true));
543 assert_can_encode_to_type(unnamed_value, Foo { hello: "world".to_string(), foo: true });
544 }
545
546 #[test]
547 fn can_encode_bitvecs() {
548 use scale_bits::bits;
549
550 assert_can_encode_to_type(
554 Value::bit_sequence(bits![0, 1, 1, 0, 0, 1]),
555 bits![0, 1, 1, 0, 0, 1],
556 );
557 assert_can_encode_to_type(value!((false)), bits![0]);
559 assert_can_encode_to_type(
560 value!((false, true, true, false, false, true)),
561 bits![0, 1, 1, 0, 0, 1],
562 );
563 assert_can_encode_to_type(value!((0u8, 1u8, 1u8, 0u8, 0u8, 1u8)), bits![0, 1, 1, 0, 0, 1]);
564 assert_can_encode_to_type(value!((0, 1, 1, 0, 0, 1)), bits![0, 1, 1, 0, 0, 1]);
565 }
566
567 #[test]
568 fn can_encode_to_compact_types() {
569 assert_can_encode_to_type(Value::u128(123), Compact(123u64));
570 assert_can_encode_to_type(Value::u128(123), Compact(123u64));
571 assert_can_encode_to_type(Value::u128(123), Compact(123u64));
572 assert_can_encode_to_type(Value::u128(123), Compact(123u64));
573
574 assert_can_encode_to_type(value!((123)), Compact(123u64));
576 assert_can_encode_to_type(value!(({foo: 123u64})), Compact(123u64));
577 }
578
579 #[test]
580 fn can_encode_skipping_struct_newtype_wrappers() {
581 #[derive(Encode, scale_info::TypeInfo)]
583 struct Foo {
584 inner: u32,
585 }
586 assert_can_encode_to_type(Value::u128(32), Foo { inner: 32 });
587
588 #[derive(Encode, scale_info::TypeInfo)]
590 struct Bar(Foo);
591 assert_can_encode_to_type(Value::u128(32), Bar(Foo { inner: 32 }));
592 assert_can_encode_to_type(value!((32u8)), Bar(Foo { inner: 32 }));
593
594 #[derive(Encode, scale_info::TypeInfo)]
596 struct SomeBytes(Vec<u8>);
597 assert_can_encode_to_type(
598 Value::from_bytes([1, 2, 3, 4, 5]),
599 SomeBytes(vec![1, 2, 3, 4, 5]),
600 );
601 assert_can_encode_to_type(Value::from_bytes([1]), SomeBytes(vec![1]));
602 }
603
604 #[test]
605 fn can_encode_skipping_value_newtype_wrappers() {
606 #[derive(Encode, scale_info::TypeInfo)]
607 struct Foo {
608 inner: u32,
609 }
610
611 assert_can_encode_to_type(
613 Value::unnamed_composite(vec![Value::u128(32)]),
614 Foo { inner: 32 },
615 );
616 assert_can_encode_to_type(
618 Value::unnamed_composite(vec![Value::unnamed_composite(vec![Value::u128(32)])]),
619 Foo { inner: 32 },
620 );
621 assert_can_encode_to_type(
623 Value::unnamed_composite(vec![Value::unnamed_composite(vec![
624 Value::unnamed_composite(vec![Value::u128(32)]),
625 ])]),
626 Foo { inner: 32 },
627 );
628 }
629
630 #[test]
633 #[cfg(feature = "__std")]
634 fn encoding_shouldnt_take_forever() {
635 panic_after(core::time::Duration::from_millis(100), || {
636 #[derive(scale_info::TypeInfo, codec::Encode)]
637 struct A(bool);
638
639 let mut buf = Vec::new();
640 let (ty_id, types) = make_type::<A>();
641 let value = Value::unnamed_composite(vec![Value::from_bytes(0u32.to_le_bytes())]);
642
643 value
644 .encode_as_type_to(ty_id, &types, &mut buf)
645 .expect_err("We tried encoding a Value of the wrong shape so this should fail");
646 })
647 }
648}