diff --git a/CHANGELOG.md b/CHANGELOG.md index 461f383..4a20d4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ The format is based on [Keep a Changelog]. [Keep a Changelog]: http://keepachangelog.com/en/1.0.0/ +## 0.12.0 - 2024-04-29 + +Update the `scale-type-resolver` dependency to 0.2.0 (and bump `scale-bits` for the same reason). + +The main changes here are: +- Type IDs are now passed by value rather than reference. +- The `Composite` type handed back in the visitor's `visit_composite()` method now exposes the name and path of the composite type being decoded, if one was provided. + ## 0.11.1 - 2024-02-16 - `scale-info` was still being pulled in via `scale-type-resolver`; this has now been fixed diff --git a/Cargo.toml b/Cargo.toml index 002644a..b11c79f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.11.1" +version = "0.12.0" authors = ["Parity Technologies "] edition = "2021" license = "Apache-2.0" @@ -17,5 +17,5 @@ keywords = ["parity", "scale", "decoding"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [workspace.dependencies] -scale-decode = { version = "0.11.1", path = "scale-decode" } -scale-decode-derive = { version = "0.11.1", path = "scale-decode-derive" } +scale-decode = { version = "0.12.0", path = "scale-decode" } +scale-decode-derive = { version = "0.12.0", path = "scale-decode-derive" } diff --git a/scale-decode-derive/src/lib.rs b/scale-decode-derive/src/lib.rs index 8507a1b..866b3bd 100644 --- a/scale-decode-derive/src/lib.rs +++ b/scale-decode-derive/src/lib.rs @@ -159,7 +159,7 @@ fn generate_enum_impl( fn visit_variant<'scale, 'info>( self, value: &mut #path_to_scale_decode::visitor::types::Variant<'scale, 'info, Self::TypeResolver>, - type_id: &::TypeId, + type_id: ::TypeId, ) -> Result, Self::Error> { #( #variant_ifs @@ -173,7 +173,7 @@ fn generate_enum_impl( fn visit_composite<'scale, 'info>( self, value: &mut #path_to_scale_decode::visitor::types::Composite<'scale, 'info, Self::TypeResolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.remaining() != 1 { return self.visit_unexpected(#path_to_scale_decode::visitor::Unexpected::Composite); @@ -183,7 +183,7 @@ fn generate_enum_impl( fn visit_tuple<'scale, 'info>( self, value: &mut #path_to_scale_decode::visitor::types::Tuple<'scale, 'info, Self::TypeResolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.remaining() != 1 { return self.visit_unexpected(#path_to_scale_decode::visitor::Unexpected::Tuple); @@ -297,14 +297,14 @@ fn generate_struct_impl( fn visit_composite<'scale, 'info>( self, value: &mut #path_to_scale_decode::visitor::types::Composite<'scale, 'info, Self::TypeResolver>, - type_id: &::TypeId, + type_id: ::TypeId, ) -> Result, Self::Error> { #visit_composite_body } fn visit_tuple<'scale, 'info>( self, value: &mut #path_to_scale_decode::visitor::types::Tuple<'scale, 'info, Self::TypeResolver>, - type_id: &::TypeId, + type_id: ::TypeId, ) -> Result, Self::Error> { #visit_tuple_body } @@ -317,9 +317,9 @@ fn generate_struct_impl( types: &'info R ) -> Result { - let mut composite = #path_to_scale_decode::visitor::types::Composite::new(input, fields, types, false); + let mut composite = #path_to_scale_decode::visitor::types::Composite::new(core::iter::empty(), input, fields, types, false); use #path_to_scale_decode::{ Visitor, IntoVisitor }; - let val = <#path_to_type #ty_generics>::into_visitor().visit_composite(&mut composite, &Default::default()); + let val = <#path_to_type #ty_generics>::into_visitor().visit_composite(&mut composite, Default::default()); // Consume any remaining bytes and update input: composite.skip_decoding()?; @@ -357,9 +357,10 @@ fn named_field_keyvals<'f>( true, // For turning named fields in scale typeinfo into named fields on struct like type: quote!(#field_ident: { - let val = *vals + let val = vals .get(&Some(#field_name)) - .ok_or_else(|| #path_to_scale_decode::Error::new(#path_to_scale_decode::error::ErrorKind::CannotFindField { name: #field_name.to_string() }))?; + .ok_or_else(|| #path_to_scale_decode::Error::new(#path_to_scale_decode::error::ErrorKind::CannotFindField { name: #field_name.to_string() }))? + .clone(); val.decode_as_type().map_err(|e| e.at_field(#field_name))? }), // For turning named fields in scale typeinfo into unnamed fields on tuple like type: diff --git a/scale-decode/Cargo.toml b/scale-decode/Cargo.toml index 0a550ec..3b1b21b 100644 --- a/scale-decode/Cargo.toml +++ b/scale-decode/Cargo.toml @@ -27,12 +27,12 @@ derive = ["dep:scale-decode-derive"] [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } -scale-bits = { version = "0.5.0", default-features = false } +scale-bits = { version = "0.6.0", default-features = false } scale-decode-derive = { workspace = true, optional = true } primitive-types = { version = "0.12.0", optional = true, default-features = false } smallvec = "1.10.0" derive_more = { version = "0.99.17", default-features = false, features = ["from", "display"] } -scale-type-resolver = { version = "0.1.1", default-features = false } +scale-type-resolver = { version = "0.2.0", default-features = false } [dev-dependencies] scale-info = { version = "2.7.0", default-features = false, features = ["bit-vec", "derive"] } @@ -40,6 +40,6 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = bitvec = { version = "1.0.1", default-features = false } trybuild = "1.0.72" # Enable the scale-info feature for testing. -scale-bits = { version = "0.5.0", default-features = false, features = ["scale-info"] } +scale-bits = { version = "0.6.0", default-features = false, features = ["scale-info"] } primitive-types = { version = "0.12.0", default-features = false, features = ["scale-info"] } -scale-type-resolver = { version = "0.1.1", default-features = false, features = ["scale-info"] } +scale-type-resolver = { version = "0.2.0", default-features = false, features = ["scale-info"] } \ No newline at end of file diff --git a/scale-decode/examples/enum_decode_as_type.rs b/scale-decode/examples/enum_decode_as_type.rs index d959f8a..6d79d57 100644 --- a/scale-decode/examples/enum_decode_as_type.rs +++ b/scale-decode/examples/enum_decode_as_type.rs @@ -63,7 +63,7 @@ impl Visitor for FooVisitor { fn visit_variant<'scale, 'resolver>( self, value: &mut scale_decode::visitor::types::Variant<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { if value.name() == "Bar" { // Here we choose to support decoding named or unnamed fields into our Bar variant. @@ -81,9 +81,12 @@ impl Visitor for FooVisitor { let vals: HashMap, _> = fields .map(|res| res.map(|item| (item.name(), item))) .collect::>()?; - let bar = *vals.get(&Some("bar")).ok_or_else(|| { - Error::new(ErrorKind::CannotFindField { name: "bar".to_owned() }) - })?; + let bar = vals + .get(&Some("bar")) + .ok_or_else(|| { + Error::new(ErrorKind::CannotFindField { name: "bar".to_owned() }) + })? + .clone(); Ok(Foo::Bar { bar: bar.decode_as_type().map_err(|e| e.at_field("bar"))? }) } } else if value.name() == "Wibble" { @@ -125,30 +128,30 @@ fn main() { let (type_id, types) = make_type::(); // We can decode via `DecodeAsType`, which is automatically implemented: - let bar_via_decode_as_type = Foo::decode_as_type(&mut &*bar_bytes, &type_id, &types).unwrap(); + let bar_via_decode_as_type = Foo::decode_as_type(&mut &*bar_bytes, type_id, &types).unwrap(); let wibble_via_decode_as_type = - Foo::decode_as_type(&mut &*wibble_bytes, &type_id, &types).unwrap(); + Foo::decode_as_type(&mut &*wibble_bytes, type_id, &types).unwrap(); let empty_via_decode_as_type = - Foo::decode_as_type(&mut &*empty_bytes, &type_id, &types).unwrap(); + Foo::decode_as_type(&mut &*empty_bytes, type_id, &types).unwrap(); // Or we can also manually use our `Visitor` impl: let bar_via_visitor = scale_decode::visitor::decode_with_visitor( &mut &*bar_bytes, - &type_id, + type_id, &types, FooVisitor::new(), ) .unwrap(); let wibble_via_visitor = scale_decode::visitor::decode_with_visitor( &mut &*wibble_bytes, - &type_id, + type_id, &types, FooVisitor::new(), ) .unwrap(); let empty_via_visitor = scale_decode::visitor::decode_with_visitor( &mut &*empty_bytes, - &type_id, + type_id, &types, FooVisitor::new(), ) diff --git a/scale-decode/examples/struct_decode_as_type.rs b/scale-decode/examples/struct_decode_as_type.rs index fdadd8a..d5da1ff 100644 --- a/scale-decode/examples/struct_decode_as_type.rs +++ b/scale-decode/examples/struct_decode_as_type.rs @@ -63,7 +63,7 @@ impl Visitor for FooVisitor { fn visit_composite<'scale, 'resolver>( self, value: &mut scale_decode::visitor::types::Composite<'scale, 'resolver, Self::TypeResolver>, - type_id: &TypeIdFor, + type_id: TypeIdFor, ) -> Result, Self::Error> { if value.has_unnamed_fields() { // handle it like a tuple if there are unnamed fields in it: @@ -73,12 +73,14 @@ impl Visitor for FooVisitor { let vals: HashMap, _> = value.map(|res| res.map(|item| (item.name(), item))).collect::>()?; - let bar = *vals + let bar = vals .get(&Some("bar")) - .ok_or_else(|| Error::new(ErrorKind::CannotFindField { name: "bar".to_owned() }))?; - let wibble = *vals + .ok_or_else(|| Error::new(ErrorKind::CannotFindField { name: "bar".to_owned() }))? + .clone(); + let wibble = vals .get(&Some("wibble")) - .ok_or_else(|| Error::new(ErrorKind::CannotFindField { name: "wibble".to_owned() }))?; + .ok_or_else(|| Error::new(ErrorKind::CannotFindField { name: "wibble".to_owned() }))? + .clone(); Ok(Foo { bar: bar.decode_as_type().map_err(|e| e.at_field("bar"))?, @@ -90,7 +92,7 @@ impl Visitor for FooVisitor { fn visit_tuple<'scale, 'resolver>( self, value: &mut scale_decode::visitor::types::Tuple<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { if value.remaining() != 2 { return Err(Error::new(ErrorKind::WrongLength { @@ -119,14 +121,14 @@ fn main() { let (type_id, types) = make_type::(); // We can decode via `DecodeAsType`, which is automatically implemented: - let foo_via_decode_as_type = Foo::decode_as_type(&mut &*foo_bytes, &type_id, &types).unwrap(); + let foo_via_decode_as_type = Foo::decode_as_type(&mut &*foo_bytes, type_id, &types).unwrap(); // We can also attempt to decode it into any other type; we'll get an error if this fails: let foo_via_decode_as_type_arc = - >::decode_as_type(&mut &*foo_bytes, &type_id, &types).unwrap(); + >::decode_as_type(&mut &*foo_bytes, type_id, &types).unwrap(); // Or we can also manually use our `Visitor` impl: let foo_via_visitor = scale_decode::visitor::decode_with_visitor( &mut &*foo_bytes, - &type_id, + type_id, &types, FooVisitor::new(), ) diff --git a/scale-decode/examples/visitor.rs b/scale-decode/examples/visitor.rs index e1e920b..3482f0f 100644 --- a/scale-decode/examples/visitor.rs +++ b/scale-decode/examples/visitor.rs @@ -67,105 +67,105 @@ impl visitor::Visitor for ValueVisitor { fn visit_bool<'scale, 'resolver>( self, value: bool, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::Bool(value)) } fn visit_char<'scale, 'resolver>( self, value: char, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::Char(value)) } fn visit_u8<'scale, 'resolver>( self, value: u8, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U8(value)) } fn visit_u16<'scale, 'resolver>( self, value: u16, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U16(value)) } fn visit_u32<'scale, 'resolver>( self, value: u32, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U32(value)) } fn visit_u64<'scale, 'resolver>( self, value: u64, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U64(value)) } fn visit_u128<'scale, 'resolver>( self, value: u128, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U128(value)) } - fn visit_u256<'scale, 'resolver>( + fn visit_u256<'resolver>( self, - value: &'scale [u8; 32], - _type_id: &TypeIdFor, - ) -> Result, Self::Error> { + value: &[u8; 32], + _type_id: TypeIdFor, + ) -> Result, Self::Error> { Ok(Value::U256(*value)) } fn visit_i8<'scale, 'resolver>( self, value: i8, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I8(value)) } fn visit_i16<'scale, 'resolver>( self, value: i16, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I16(value)) } fn visit_i32<'scale, 'resolver>( self, value: i32, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I32(value)) } fn visit_i64<'scale, 'resolver>( self, value: i64, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I64(value)) } fn visit_i128<'scale, 'resolver>( self, value: i128, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I128(value)) } - fn visit_i256<'scale, 'resolver>( + fn visit_i256<'resolver>( self, - value: &'scale [u8; 32], - _type_id: &TypeIdFor, - ) -> Result, Self::Error> { + value: &[u8; 32], + _type_id: TypeIdFor, + ) -> Result, Self::Error> { Ok(Value::I256(*value)) } fn visit_sequence<'scale, 'resolver>( self, value: &mut Sequence<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor::new()) { @@ -177,7 +177,7 @@ impl visitor::Visitor for ValueVisitor { fn visit_composite<'scale, 'resolver>( self, value: &mut Composite<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; for item in value.by_ref() { @@ -191,7 +191,7 @@ impl visitor::Visitor for ValueVisitor { fn visit_tuple<'scale, 'resolver>( self, value: &mut Tuple<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor::new()) { @@ -203,14 +203,14 @@ impl visitor::Visitor for ValueVisitor { fn visit_str<'scale, 'resolver>( self, value: &mut Str<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::Str(value.as_str()?.to_owned())) } fn visit_variant<'scale, 'resolver>( self, value: &mut Variant<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; let fields = value.fields(); @@ -225,7 +225,7 @@ impl visitor::Visitor for ValueVisitor { fn visit_array<'scale, 'resolver>( self, value: &mut Array<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor::new()) { @@ -237,7 +237,7 @@ impl visitor::Visitor for ValueVisitor { fn visit_bitsequence<'scale, 'resolver>( self, value: &mut BitSequence<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let bools: Result = value.decode()?.collect(); Ok(Value::BitSequence(bools?)) @@ -265,7 +265,7 @@ fn main() { assert_eq!( scale_decode::visitor::decode_with_visitor( &mut &*bytes, - &type_id, + type_id, &types, ValueVisitor::new() ) diff --git a/scale-decode/src/impls/mod.rs b/scale-decode/src/impls/mod.rs index af8781e..16ec900 100644 --- a/scale-decode/src/impls/mod.rs +++ b/scale-decode/src/impls/mod.rs @@ -70,7 +70,7 @@ macro_rules! visit_single_field_composite_tuple_impls { fn visit_composite<'scale, 'resolver>( self, value: &mut $crate::visitor::types::Composite<'scale, 'resolver, $type_resolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.remaining() != 1 { return self.visit_unexpected($crate::visitor::Unexpected::Composite); @@ -80,7 +80,7 @@ macro_rules! visit_single_field_composite_tuple_impls { fn visit_tuple<'scale, 'resolver>( self, value: &mut $crate::visitor::types::Tuple<'scale, 'resolver, $type_resolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.remaining() != 1 { return self.visit_unexpected($crate::visitor::Unexpected::Tuple); @@ -98,7 +98,7 @@ impl Visitor for BasicVisitor { fn visit_char<'scale, 'resolver>( self, value: char, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { Ok(value) } @@ -114,7 +114,7 @@ impl Visitor for BasicVisitor { fn visit_bool<'scale, 'resolver>( self, value: bool, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { Ok(value) } @@ -130,7 +130,7 @@ impl Visitor for BasicVisitor { fn visit_str<'scale, 'resolver>( self, value: &mut Str<'scale>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { let s = value.as_str()?.to_owned(); Ok(s) @@ -147,7 +147,7 @@ impl Visitor for BasicVisitor { fn visit_bitsequence<'scale, 'resolver>( self, value: &mut BitSequence<'scale>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { value .decode()? @@ -166,7 +166,7 @@ impl Visitor for BasicVisitor, R> { fn visit_tuple<'scale, 'resolver>( self, value: &mut Tuple<'scale, 'resolver, R>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.remaining() == 0 { Ok(PhantomData) @@ -177,7 +177,7 @@ impl Visitor for BasicVisitor, R> { fn visit_composite<'scale, 'resolver>( self, value: &mut Composite<'scale, 'resolver, R>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.remaining() == 0 { Ok(PhantomData) @@ -205,7 +205,7 @@ macro_rules! impl_into_visitor_like { fn unchecked_decode_as_type<'scale, 'resolver>( self, input: &mut &'scale [u8], - type_id: &::TypeId, + type_id: ::TypeId, types: &'resolver Self::TypeResolver, ) -> DecodeAsTypeResult, Self::Error>> { // Use the source visitor to decode into some type: @@ -242,7 +242,7 @@ where fn unchecked_decode_as_type<'scale, 'resolver>( self, input: &mut &'scale [u8], - type_id: &::TypeId, + type_id: ::TypeId, types: &'resolver Self::TypeResolver, ) -> DecodeAsTypeResult, Self::Error>> { // Use the ToOwned visitor to decode into some type: @@ -279,14 +279,14 @@ macro_rules! impl_decode_seq_via_collect { fn visit_sequence<'scale, 'resolver>( self, value: &mut Sequence<'scale, 'resolver, Resolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { decode_items_using::<_, _, $generic>(value).collect() } fn visit_array<'scale, 'resolver>( self, value: &mut Array<'scale, 'resolver, Resolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { decode_items_using::<_, _, $generic>(value).collect() } @@ -322,14 +322,14 @@ impl Visitor for BasicVisitor<[ fn visit_sequence<'scale, 'resolver>( self, value: &mut Sequence<'scale, 'resolver, R>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { array_method_impl!(value, [T; N]) } fn visit_array<'scale, 'resolver>( self, value: &mut Array<'scale, 'resolver, R>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { array_method_impl!(value, [T; N]) } @@ -351,7 +351,7 @@ impl Visitor for BasicVisitor( self, value: &mut Composite<'scale, 'resolver, R>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { let mut map = BTreeMap::new(); while value.remaining() > 0 { @@ -384,7 +384,7 @@ impl Visitor for BasicVisitor, R> { fn visit_variant<'scale, 'resolver>( self, value: &mut Variant<'scale, 'resolver, R>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.name() == "Some" && value.fields().remaining() == 1 { let val = value @@ -415,7 +415,7 @@ impl Visitor for BasicVisitor( self, value: &mut Variant<'scale, 'resolver, R>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { if value.name() == "Ok" && value.fields().remaining() == 1 { let val = value @@ -450,7 +450,7 @@ macro_rules! visit_number_fn_impl { fn $name<'scale, 'resolver>( self, value: $ty, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { let $res = value; let n = $expr.ok_or_else(|| { @@ -552,7 +552,7 @@ macro_rules! decode_inner_type_when_one_tuple_entry { fn unchecked_decode_as_type<'scale, 'resolver>( self, input: &mut &'scale [u8], - type_id: &::TypeId, + type_id: ::TypeId, types: &'resolver Self::TypeResolver, ) -> DecodeAsTypeResult, Self::Error>> { use scale_type_resolver::{ResolvedTypeVisitor, UnhandledKind}; @@ -560,7 +560,7 @@ macro_rules! decode_inner_type_when_one_tuple_entry { // Match on the resolved kind; try to decode as inner type if it's not a // composite, tuple, or a type ID we can't find. Else fall back to default. struct TryDecodeAsInner(PhantomData); - impl<'resolver, TypeId: scale_type_resolver::TypeId + 'resolver> + impl<'resolver, TypeId: scale_type_resolver::TypeId + 'static> ResolvedTypeVisitor<'resolver> for TryDecodeAsInner { type TypeId = TypeId; @@ -576,7 +576,9 @@ macro_rules! decode_inner_type_when_one_tuple_entry { } // If error decoding, or false, just fall back to default behaviour and don't try to decode as inner. - if let Err(_) | Ok(false) = types.resolve_type(type_id, TryDecodeAsInner(PhantomData)) { + if let Err(_) | Ok(false) = + types.resolve_type(type_id.clone(), TryDecodeAsInner(PhantomData)) + { return DecodeAsTypeResult::Skipped(self); } @@ -608,14 +610,14 @@ macro_rules! impl_decode_tuple { fn visit_composite<'scale, 'resolver>( self, value: &mut Composite<'scale, 'resolver, Resolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { tuple_method_impl!(($($t,)*), value) } fn visit_tuple<'scale, 'resolver>( self, value: &mut Tuple<'scale, 'resolver, Resolver>, - _type_id: &::TypeId, + _type_id: ::TypeId, ) -> Result, Self::Error> { tuple_method_impl!(($($t,)*), value) } @@ -636,11 +638,11 @@ macro_rules! impl_decode_tuple { where $( $t: IntoVisitor, )* { fn decode_as_fields<'resolver, Resolver: TypeResolver>(input: &mut &[u8], fields: &mut dyn FieldIter<'resolver, Resolver::TypeId>, types: &'resolver Resolver) -> Result { - let mut composite = crate::visitor::types::Composite::new(input, fields, types, false); + let mut composite = crate::visitor::types::Composite::new(core::iter::empty(), input, fields, types, false); // [jsdw] TODO: Passing a "default type ID" to a visitor just to satisfy the signature is // a bit hideous (and requires `TypeId: Default`). Can we re-work this to avoid? - let val = <($($t,)*)>::into_visitor().visit_composite(&mut composite, &Default::default()); + let val = <($($t,)*)>::into_visitor().visit_composite(&mut composite, Default::default()); // Skip over bytes that we decoded: composite.skip_decoding()?; @@ -719,7 +721,7 @@ mod test { let (type_id, types) = make_type::(); let encoded = a.encode(); let decoded = - B::decode_as_type(&mut &*encoded, &type_id, &types).expect("should be able to decode"); + B::decode_as_type(&mut &*encoded, type_id, &types).expect("should be able to decode"); assert_eq!(&decoded, b); } @@ -766,11 +768,11 @@ mod test { let new_foo = match &types.resolve(ty).unwrap().type_def { scale_info::TypeDef::Composite(c) => { - let mut field_iter = c.fields.iter().map(|f| Field::new(&f.ty.id, f.name)); + let mut field_iter = c.fields.iter().map(|f| Field::new(f.ty.id, f.name)); Foo::decode_as_fields(foo_encoded_cursor, &mut field_iter, &types).unwrap() } scale_info::TypeDef::Tuple(t) => { - let mut field_iter = t.fields.iter().map(|f| Field::unnamed(&f.id)); + let mut field_iter = t.fields.iter().map(|f| Field::unnamed(f.id)); Foo::decode_as_fields(foo_encoded_cursor, &mut field_iter, &types).unwrap() } _ => { diff --git a/scale-decode/src/impls/primitive_types.rs b/scale-decode/src/impls/primitive_types.rs index 88eff7a..ff788f1 100644 --- a/scale-decode/src/impls/primitive_types.rs +++ b/scale-decode/src/impls/primitive_types.rs @@ -32,7 +32,7 @@ macro_rules! impl_visitor { fn unchecked_decode_as_type<'scale, 'resolver>( self, input: &mut &'scale [u8], - type_id: &::TypeId, + type_id: ::TypeId, types: &'resolver Self::TypeResolver, ) -> crate::visitor::DecodeAsTypeResult< Self, diff --git a/scale-decode/src/lib.rs b/scale-decode/src/lib.rs index b9ab467..688831e 100644 --- a/scale-decode/src/lib.rs +++ b/scale-decode/src/lib.rs @@ -68,7 +68,7 @@ where { let (type_id, types) = get_type_info::(); let a_bytes = a.encode(); - let new_b = B::decode_as_type(&mut &*a_bytes, &type_id, &types).unwrap(); + let new_b = B::decode_as_type(&mut &*a_bytes, type_id, &types).unwrap(); assert_eq!(b, new_b); } @@ -170,7 +170,7 @@ pub trait DecodeAsType: Sized + IntoVisitor { /// not used in the course of decoding are still pointed to after decoding is complete. fn decode_as_type( input: &mut &[u8], - type_id: &R::TypeId, + type_id: R::TypeId, types: &R, ) -> Result { Self::decode_as_type_maybe_compact(input, type_id, types, false) @@ -184,7 +184,7 @@ pub trait DecodeAsType: Sized + IntoVisitor { #[doc(hidden)] fn decode_as_type_maybe_compact( input: &mut &[u8], - type_id: &R::TypeId, + type_id: R::TypeId, types: &R, is_compact: bool, ) -> Result; @@ -193,7 +193,7 @@ pub trait DecodeAsType: Sized + IntoVisitor { impl DecodeAsType for T { fn decode_as_type_maybe_compact( input: &mut &[u8], - type_id: &R::TypeId, + type_id: R::TypeId, types: &R, is_compact: bool, ) -> Result { diff --git a/scale-decode/src/visitor/decode.rs b/scale-decode/src/visitor/decode.rs index 766892c..a80f234 100644 --- a/scale-decode/src/visitor/decode.rs +++ b/scale-decode/src/visitor/decode.rs @@ -21,8 +21,8 @@ use alloc::format; use alloc::string::ToString; use codec::{self, Decode}; use scale_type_resolver::{ - BitsOrderFormat, BitsStoreFormat, FieldIter, Primitive, ResolvedTypeVisitor, TypeResolver, - UnhandledKind, VariantIter, + BitsOrderFormat, BitsStoreFormat, FieldIter, PathIter, Primitive, ResolvedTypeVisitor, + TypeResolver, UnhandledKind, VariantIter, }; /// Decode data according to the type ID and type resolver provided. @@ -31,7 +31,7 @@ use scale_type_resolver::{ /// will be called depending on the type that needs to be decoded. pub fn decode_with_visitor<'scale, 'resolver, V: Visitor>( data: &mut &'scale [u8], - ty_id: &TypeIdFor, + ty_id: TypeIdFor, types: &'resolver V::TypeResolver, visitor: V, ) -> Result, V::Error> { @@ -40,18 +40,18 @@ pub fn decode_with_visitor<'scale, 'resolver, V: Visitor>( pub fn decode_with_visitor_maybe_compact<'scale, 'resolver, V: Visitor>( data: &mut &'scale [u8], - ty_id: &TypeIdFor, + ty_id: TypeIdFor, types: &'resolver V::TypeResolver, visitor: V, is_compact: bool, ) -> Result, V::Error> { // Provide option to "bail out" and do something custom first. - let visitor = match visitor.unchecked_decode_as_type(data, ty_id, types) { + let visitor = match visitor.unchecked_decode_as_type(data, ty_id.clone(), types) { DecodeAsTypeResult::Decoded(r) => return r, DecodeAsTypeResult::Skipped(v) => v, }; - let decoder = Decoder::new(data, types, ty_id, visitor, is_compact); + let decoder = Decoder::new(data, types, ty_id.clone(), visitor, is_compact); let res = types.resolve_type(ty_id, decoder); match res { @@ -72,7 +72,7 @@ pub fn decode_with_visitor_maybe_compact<'scale, 'resolver, V: Visitor>( /// hand back the decoded value (or some nice interface to allow the user to decode the value). struct Decoder<'a, 'scale, 'resolver, V: Visitor> { data: &'a mut &'scale [u8], - type_id: &'a TypeIdFor, + type_id: TypeIdFor, types: &'resolver V::TypeResolver, visitor: V, is_compact: bool, @@ -82,7 +82,7 @@ impl<'a, 'scale, 'resolver, V: Visitor> Decoder<'a, 'scale, 'resolver, V> { fn new( data: &'a mut &'scale [u8], types: &'resolver V::TypeResolver, - type_id: &'a TypeIdFor, + type_id: TypeIdFor, visitor: V, is_compact: bool, ) -> Self { @@ -90,8 +90,8 @@ impl<'a, 'scale, 'resolver, V: Visitor> Decoder<'a, 'scale, 'resolver, V> { } } -impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> - for Decoder<'a, 'scale, 'resolver, V> +impl<'temp, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> + for Decoder<'temp, 'scale, 'resolver, V> { type TypeId = TypeIdFor; type Value = Result, V::Error>; @@ -109,8 +109,9 @@ impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> Err(DecodeError::TypeIdNotFound(format!("{type_id:?}")).into()) } - fn visit_composite(self, mut fields: Fields) -> Self::Value + fn visit_composite(self, path: Path, mut fields: Fields) -> Self::Value where + Path: PathIter<'resolver>, Fields: FieldIter<'resolver, Self::TypeId>, { // guard against invalid compact types: only composites with 1 field can be compact encoded @@ -118,7 +119,7 @@ impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> return Err(DecodeError::CannotDecodeCompactIntoType.into()); } - let mut items = Composite::new(self.data, &mut fields, self.types, self.is_compact); + let mut items = Composite::new(path, self.data, &mut fields, self.types, self.is_compact); let res = self.visitor.visit_composite(&mut items, self.type_id); // Skip over any bytes that the visitor chose not to decode: @@ -128,9 +129,10 @@ impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> res } - fn visit_variant(self, variants: Var) -> Self::Value + fn visit_variant(self, _path: Path, variants: Var) -> Self::Value where - Fields: FieldIter<'resolver, Self::TypeId> + 'resolver, + Path: PathIter<'resolver>, + Fields: FieldIter<'resolver, Self::TypeId>, Var: VariantIter<'resolver, Fields>, { if self.is_compact { @@ -147,7 +149,10 @@ impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> res } - fn visit_sequence(self, inner_type_id: &'resolver Self::TypeId) -> Self::Value { + fn visit_sequence(self, _path: Path, inner_type_id: Self::TypeId) -> Self::Value + where + Path: PathIter<'resolver>, + { if self.is_compact { return Err(DecodeError::CannotDecodeCompactIntoType.into()); } @@ -162,7 +167,7 @@ impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> res } - fn visit_array(self, inner_type_id: &'resolver Self::TypeId, len: usize) -> Self::Value { + fn visit_array(self, inner_type_id: Self::TypeId, len: usize) -> Self::Value { if self.is_compact { return Err(DecodeError::CannotDecodeCompactIntoType.into()); } @@ -179,7 +184,7 @@ impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> fn visit_tuple(self, type_ids: TypeIds) -> Self::Value where - TypeIds: ExactSizeIterator, + TypeIds: ExactSizeIterator, { // guard against invalid compact types: only composites with 1 field can be compact encoded if self.is_compact && type_ids.len() != 1 { @@ -329,7 +334,7 @@ impl<'a, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver> } } - fn visit_compact(self, inner_type_id: &'resolver Self::TypeId) -> Self::Value { + fn visit_compact(self, inner_type_id: Self::TypeId) -> Self::Value { decode_with_visitor_maybe_compact(self.data, inner_type_id, self.types, self.visitor, true) } diff --git a/scale-decode/src/visitor/mod.rs b/scale-decode/src/visitor/mod.rs index 0ca7c32..00ad589 100644 --- a/scale-decode/src/visitor/mod.rs +++ b/scale-decode/src/visitor/mod.rs @@ -54,7 +54,7 @@ pub trait Visitor: Sized { fn unchecked_decode_as_type<'scale, 'resolver>( self, _input: &mut &'scale [u8], - _type_id: &TypeIdFor, + _type_id: TypeIdFor, _types: &'resolver Self::TypeResolver, ) -> DecodeAsTypeResult, Self::Error>> { DecodeAsTypeResult::Skipped(self) @@ -74,7 +74,7 @@ pub trait Visitor: Sized { fn visit_bool<'scale, 'resolver>( self, _value: bool, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Bool) } @@ -82,7 +82,7 @@ pub trait Visitor: Sized { fn visit_char<'scale, 'resolver>( self, _value: char, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Char) } @@ -90,7 +90,7 @@ pub trait Visitor: Sized { fn visit_u8<'scale, 'resolver>( self, _value: u8, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::U8) } @@ -98,7 +98,7 @@ pub trait Visitor: Sized { fn visit_u16<'scale, 'resolver>( self, _value: u16, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::U16) } @@ -106,7 +106,7 @@ pub trait Visitor: Sized { fn visit_u32<'scale, 'resolver>( self, _value: u32, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::U32) } @@ -114,7 +114,7 @@ pub trait Visitor: Sized { fn visit_u64<'scale, 'resolver>( self, _value: u64, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::U64) } @@ -122,23 +122,23 @@ pub trait Visitor: Sized { fn visit_u128<'scale, 'resolver>( self, _value: u128, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::U128) } /// Called when a u256 is seen in the input bytes. - fn visit_u256<'scale, 'resolver>( + fn visit_u256<'resolver>( self, - _value: &'scale [u8; 32], - _type_id: &TypeIdFor, - ) -> Result, Self::Error> { + _value: &[u8; 32], + _type_id: TypeIdFor, + ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::U256) } /// Called when an i8 is seen in the input bytes. fn visit_i8<'scale, 'resolver>( self, _value: i8, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::I8) } @@ -146,7 +146,7 @@ pub trait Visitor: Sized { fn visit_i16<'scale, 'resolver>( self, _value: i16, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::I16) } @@ -154,7 +154,7 @@ pub trait Visitor: Sized { fn visit_i32<'scale, 'resolver>( self, _value: i32, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::I32) } @@ -162,7 +162,7 @@ pub trait Visitor: Sized { fn visit_i64<'scale, 'resolver>( self, _value: i64, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::I64) } @@ -170,23 +170,23 @@ pub trait Visitor: Sized { fn visit_i128<'scale, 'resolver>( self, _value: i128, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::I128) } /// Called when an i256 is seen in the input bytes. - fn visit_i256<'scale, 'resolver>( + fn visit_i256<'resolver>( self, - _value: &'scale [u8; 32], - _type_id: &TypeIdFor, - ) -> Result, Self::Error> { + _value: &[u8; 32], + _type_id: TypeIdFor, + ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::I256) } /// Called when a sequence of values is seen in the input bytes. fn visit_sequence<'scale, 'resolver>( self, _value: &mut Sequence<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Sequence) } @@ -194,7 +194,7 @@ pub trait Visitor: Sized { fn visit_composite<'scale, 'resolver>( self, _value: &mut Composite<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Composite) } @@ -202,7 +202,7 @@ pub trait Visitor: Sized { fn visit_tuple<'scale, 'resolver>( self, _value: &mut Tuple<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Tuple) } @@ -210,7 +210,7 @@ pub trait Visitor: Sized { fn visit_str<'scale, 'resolver>( self, _value: &mut Str<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Str) } @@ -218,7 +218,7 @@ pub trait Visitor: Sized { fn visit_variant<'scale, 'resolver>( self, _value: &mut Variant<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Variant) } @@ -226,7 +226,7 @@ pub trait Visitor: Sized { fn visit_array<'scale, 'resolver>( self, _value: &mut Array<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Array) } @@ -234,7 +234,7 @@ pub trait Visitor: Sized { fn visit_bitsequence<'scale, 'resolver>( self, _value: &mut BitSequence<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { self.visit_unexpected(Unexpected::Bitsequence) } @@ -413,7 +413,7 @@ where fn unchecked_decode_as_type<'scale, 'resolver>( self, input: &mut &'scale [u8], - type_id: &TypeIdFor, + type_id: TypeIdFor, types: &'resolver Self::TypeResolver, ) -> DecodeAsTypeResult, Self::Error>> { let res = decode_with_visitor(input, type_id, types, self.0).map_err(Into::into); @@ -480,105 +480,105 @@ mod test { fn visit_bool<'scale, 'resolver>( self, value: bool, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::Bool(value)) } fn visit_char<'scale, 'resolver>( self, value: char, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::Char(value)) } fn visit_u8<'scale, 'resolver>( self, value: u8, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U8(value)) } fn visit_u16<'scale, 'resolver>( self, value: u16, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U16(value)) } fn visit_u32<'scale, 'resolver>( self, value: u32, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U32(value)) } fn visit_u64<'scale, 'resolver>( self, value: u64, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U64(value)) } fn visit_u128<'scale, 'resolver>( self, value: u128, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::U128(value)) } - fn visit_u256<'scale, 'resolver>( + fn visit_u256<'resolver>( self, - value: &'scale [u8; 32], - _type_id: &TypeIdFor, - ) -> Result, Self::Error> { + value: &[u8; 32], + _type_id: TypeIdFor, + ) -> Result, Self::Error> { Ok(Value::U256(*value)) } fn visit_i8<'scale, 'resolver>( self, value: i8, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I8(value)) } fn visit_i16<'scale, 'resolver>( self, value: i16, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I16(value)) } fn visit_i32<'scale, 'resolver>( self, value: i32, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I32(value)) } fn visit_i64<'scale, 'resolver>( self, value: i64, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I64(value)) } fn visit_i128<'scale, 'resolver>( self, value: i128, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::I128(value)) } - fn visit_i256<'scale, 'resolver>( + fn visit_i256<'resolver>( self, - value: &'scale [u8; 32], - _type_id: &TypeIdFor, - ) -> Result, Self::Error> { + value: &[u8; 32], + _type_id: TypeIdFor, + ) -> Result, Self::Error> { Ok(Value::I256(*value)) } fn visit_sequence<'scale, 'resolver>( self, value: &mut Sequence<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor::new()) { @@ -590,7 +590,7 @@ mod test { fn visit_composite<'scale, 'resolver>( self, value: &mut Composite<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; for item in value.by_ref() { @@ -604,7 +604,7 @@ mod test { fn visit_tuple<'scale, 'resolver>( self, value: &mut Tuple<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor::new()) { @@ -616,14 +616,14 @@ mod test { fn visit_str<'scale, 'resolver>( self, value: &mut Str<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { Ok(Value::Str(value.as_str()?.to_owned())) } fn visit_variant<'scale, 'resolver>( self, value: &mut Variant<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; let fields = value.fields(); @@ -638,7 +638,7 @@ mod test { fn visit_array<'scale, 'resolver>( self, value: &mut Array<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor::new()) { @@ -650,7 +650,7 @@ mod test { fn visit_bitsequence<'scale, 'resolver>( self, value: &mut BitSequence<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let bools: Result = value.decode()?.collect(); Ok(Value::BitSequence(bools?)) @@ -684,7 +684,7 @@ mod test { let (id, types) = make_type::(); let bytes = &mut &*encoded; let val = - decode_with_visitor(bytes, &id, &types, visitor).expect("decoding should not error"); + decode_with_visitor(bytes, id, &types, visitor).expect("decoding should not error"); assert_eq!(bytes.len(), 0, "Decoding should consume all bytes"); assert_eq!(val, expected); @@ -972,7 +972,7 @@ mod test { fn visit_str<'scale, 'resolver>( self, value: &mut Str<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { value.as_str() } @@ -988,7 +988,7 @@ mod test { fn visit_tuple<'scale, 'resolver>( self, value: &mut Tuple<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let fst = value.decode_item(ZeroCopyStrVisitor).unwrap()?; let snd = value.decode_item(ZeroCopyStrVisitor).unwrap()?; @@ -998,7 +998,7 @@ mod test { let (ty_id, types) = make_type::<(&str, &str)>(); let decoded = - decode_with_visitor(&mut &*input_encoded, &ty_id, &types, ZeroCopyPairVisitor).unwrap(); + decode_with_visitor(&mut &*input_encoded, ty_id, &types, ZeroCopyPairVisitor).unwrap(); assert_eq!(decoded, ("hello", "world")); } @@ -1025,7 +1025,7 @@ mod test { fn visit_str<'scale, 'resolver>( self, value: &mut Str<'scale>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { value.as_str() } @@ -1042,7 +1042,7 @@ mod test { fn visit_composite<'scale, 'resolver>( self, value: &mut Composite<'scale, 'resolver, Self::TypeResolver>, - _type_id: &TypeIdFor, + _type_id: TypeIdFor, ) -> Result, Self::Error> { let mut vals = alloc::collections::BTreeMap::<&'resolver str, &'scale str>::new(); for item in value { @@ -1058,7 +1058,7 @@ mod test { // Decode and check: let (ty_id, types) = make_type::(); let decoded = - decode_with_visitor(&mut &*input_encoded, &ty_id, &types, ZeroCopyMapVisitor).unwrap(); + decode_with_visitor(&mut &*input_encoded, ty_id, &types, ZeroCopyMapVisitor).unwrap(); assert_eq!(decoded, BTreeMap::from_iter([("hello", "hi"), ("world", "planet")])); } @@ -1079,16 +1079,16 @@ mod test { fn unchecked_decode_as_type<'scale, 'resolver>( self, input: &mut &'scale [u8], - type_id: &u32, + type_id: u32, _types: &'resolver scale_info::PortableRegistry, ) -> DecodeAsTypeResult, Self::Error>> { - DecodeAsTypeResult::Decoded(Ok((*input, *type_id))) + DecodeAsTypeResult::Decoded(Ok((*input, type_id))) } } let decoded = - decode_with_visitor(&mut &*input_encoded, &ty_id, &types, BailOutVisitor).unwrap(); + decode_with_visitor(&mut &*input_encoded, ty_id, &types, BailOutVisitor).unwrap(); assert_eq!(decoded, (&*input_encoded, ty_id)); // We can also use this functionality to "fall-back" to a Decode impl @@ -1102,7 +1102,7 @@ mod test { fn unchecked_decode_as_type<'scale, 'resolver>( self, input: &mut &'scale [u8], - _type_id: &TypeIdFor, + _type_id: TypeIdFor, _types: &'resolver scale_info::PortableRegistry, ) -> DecodeAsTypeResult, Self::Error>> { @@ -1112,7 +1112,7 @@ mod test { let decoded: (String, String) = decode_with_visitor( &mut &*input_encoded, - &ty_id, + ty_id, &types, CodecDecodeVisitor(core::marker::PhantomData), ) diff --git a/scale-decode/src/visitor/types/array.rs b/scale-decode/src/visitor/types/array.rs index 2ad49a8..52ccbdf 100644 --- a/scale-decode/src/visitor/types/array.rs +++ b/scale-decode/src/visitor/types/array.rs @@ -23,7 +23,7 @@ use scale_type_resolver::TypeResolver; pub struct Array<'scale, 'resolver, R: TypeResolver> { bytes: &'scale [u8], item_bytes: &'scale [u8], - type_id: &'resolver R::TypeId, + type_id: R::TypeId, types: &'resolver R, remaining: usize, } @@ -31,7 +31,7 @@ pub struct Array<'scale, 'resolver, R: TypeResolver> { impl<'scale, 'resolver, R: TypeResolver> Array<'scale, 'resolver, R> { pub(crate) fn new( bytes: &'scale [u8], - type_id: &'resolver R::TypeId, + type_id: R::TypeId, len: usize, types: &'resolver R, ) -> Array<'scale, 'resolver, R> { @@ -74,7 +74,7 @@ impl<'scale, 'resolver, R: TypeResolver> Array<'scale, 'resolver, R> { let b = &mut self.item_bytes; // Don't return here; decrement bytes and remaining properly first and then return, so that // calling decode_item again works as expected. - let res = crate::visitor::decode_with_visitor(b, self.type_id, self.types, visitor); + let res = crate::visitor::decode_with_visitor(b, self.type_id.clone(), self.types, visitor); self.item_bytes = *b; self.remaining -= 1; Some(res) @@ -97,21 +97,26 @@ impl<'scale, 'resolver, R: TypeResolver> Iterator for Array<'scale, 'resolver, R let num_bytes_after = self.item_bytes.len(); let res_bytes = &item_bytes[..num_bytes_before - num_bytes_after]; - Some(Ok(ArrayItem { bytes: res_bytes, type_id: self.type_id, types: self.types })) + Some(Ok(ArrayItem { bytes: res_bytes, type_id: self.type_id.clone(), types: self.types })) } } /// A single item in the array. pub struct ArrayItem<'scale, 'resolver, R: TypeResolver> { bytes: &'scale [u8], - type_id: &'resolver R::TypeId, + type_id: R::TypeId, types: &'resolver R, } -impl<'scale, 'resolver, R: TypeResolver> Copy for ArrayItem<'scale, 'resolver, R> {} +impl<'scale, 'resolver, R> Copy for ArrayItem<'scale, 'resolver, R> +where + R: TypeResolver, + R::TypeId: Copy, +{ +} impl<'scale, 'resolver, R: TypeResolver> Clone for ArrayItem<'scale, 'resolver, R> { fn clone(&self) -> Self { - *self + ArrayItem { bytes: self.bytes, types: self.types, type_id: self.type_id.clone() } } } @@ -122,18 +127,23 @@ impl<'scale, 'resolver, R: TypeResolver> ArrayItem<'scale, 'resolver, R> { } /// The type ID associated with this item. pub fn type_id(&self) -> &R::TypeId { - self.type_id + &self.type_id } /// Decode this item using a visitor. pub fn decode_with_visitor>( &self, visitor: V, ) -> Result, V::Error> { - crate::visitor::decode_with_visitor(&mut &*self.bytes, self.type_id, self.types, visitor) + crate::visitor::decode_with_visitor( + &mut &*self.bytes, + self.type_id.clone(), + self.types, + visitor, + ) } /// Decode this item into a specific type via [`DecodeAsType`]. pub fn decode_as_type(&self) -> Result { - T::decode_as_type(&mut &*self.bytes, self.type_id, self.types) + T::decode_as_type(&mut &*self.bytes, self.type_id.clone(), self.types) } } diff --git a/scale-decode/src/visitor/types/composite.rs b/scale-decode/src/visitor/types/composite.rs index 4d3d028..e195c87 100644 --- a/scale-decode/src/visitor/types/composite.rs +++ b/scale-decode/src/visitor/types/composite.rs @@ -24,6 +24,7 @@ pub struct Composite<'scale, 'resolver, R: TypeResolver> { bytes: &'scale [u8], item_bytes: &'scale [u8], fields: smallvec::SmallVec<[Field<'resolver, R::TypeId>; 16]>, + path: smallvec::SmallVec<[&'resolver str; 5]>, next_field_idx: usize, types: &'resolver R, is_compact: bool, @@ -33,13 +34,23 @@ impl<'scale, 'resolver, R: TypeResolver> Composite<'scale, 'resolver, R> { // Used in macros, but not really expected to be used elsewhere. #[doc(hidden)] pub fn new( + path: impl Iterator, bytes: &'scale [u8], fields: &mut dyn FieldIter<'resolver, R::TypeId>, types: &'resolver R, is_compact: bool, ) -> Composite<'scale, 'resolver, R> { + let path = smallvec::SmallVec::from_iter(path); let fields = smallvec::SmallVec::from_iter(fields); - Composite { bytes, item_bytes: bytes, fields, types, next_field_idx: 0, is_compact } + Composite { path, bytes, item_bytes: bytes, fields, types, next_field_idx: 0, is_compact } + } + /// Return the name of the composite type, if one was given. + pub fn name(&self) -> Option<&'resolver str> { + self.path.iter().last().copied() + } + /// Return the full path to the composite type (including the name) if one was given. + pub fn path(&self) -> impl Iterator + '_ { + self.path.iter().copied() } /// Skip over all bytes associated with this composite type. After calling this, /// [`Self::bytes_from_undecoded()`] will represent the bytes after this composite type. @@ -98,7 +109,7 @@ impl<'scale, 'resolver, R: TypeResolver> Composite<'scale, 'resolver, R> { // Decode the bytes: let res = crate::visitor::decode_with_visitor_maybe_compact( b, - field.id, + field.id.clone(), self.types, visitor, self.is_compact, @@ -122,7 +133,7 @@ impl<'scale, 'resolver, R: TypeResolver> Iterator for Composite<'scale, 'resolve type Item = Result, DecodeError>; fn next(&mut self) -> Option { // Record details we need before we decode and skip over the thing: - let field = *self.fields.get(self.next_field_idx)?; + let field = self.fields.get(self.next_field_idx)?.clone(); let num_bytes_before = self.item_bytes.len(); let item_bytes = self.item_bytes; @@ -152,10 +163,14 @@ pub struct CompositeField<'scale, 'resolver, R: TypeResolver> { is_compact: bool, } -impl<'scale, 'resolver, R: TypeResolver> Copy for CompositeField<'scale, 'resolver, R> {} impl<'scale, 'resolver, R: TypeResolver> Clone for CompositeField<'scale, 'resolver, R> { fn clone(&self) -> Self { - *self + CompositeField { + bytes: self.bytes, + types: self.types, + is_compact: self.is_compact, + field: self.field.clone(), + } } } @@ -170,7 +185,7 @@ impl<'scale, 'resolver, R: TypeResolver> CompositeField<'scale, 'resolver, R> { } /// The type ID associated with this field. pub fn type_id(&self) -> &R::TypeId { - self.field.id + &self.field.id } /// If the field is compact encoded pub fn is_compact(&self) -> bool { @@ -183,7 +198,7 @@ impl<'scale, 'resolver, R: TypeResolver> CompositeField<'scale, 'resolver, R> { ) -> Result, V::Error> { crate::visitor::decode_with_visitor_maybe_compact( &mut &*self.bytes, - self.field.id, + self.field.id.clone(), self.types, visitor, self.is_compact, @@ -193,7 +208,7 @@ impl<'scale, 'resolver, R: TypeResolver> CompositeField<'scale, 'resolver, R> { pub fn decode_as_type(&self) -> Result { T::decode_as_type_maybe_compact( &mut &*self.bytes, - self.field.id, + self.field.id.clone(), self.types, self.is_compact, ) diff --git a/scale-decode/src/visitor/types/sequence.rs b/scale-decode/src/visitor/types/sequence.rs index eef5e42..b9ada17 100644 --- a/scale-decode/src/visitor/types/sequence.rs +++ b/scale-decode/src/visitor/types/sequence.rs @@ -33,7 +33,7 @@ pub struct Sequence<'scale, 'resolver, R: TypeResolver> { impl<'scale, 'resolver, R: TypeResolver> Sequence<'scale, 'resolver, R> { pub(crate) fn new( bytes: &'scale [u8], - type_id: &'resolver R::TypeId, + type_id: R::TypeId, types: &'resolver R, ) -> Result, DecodeError> { // Sequences are prefixed with their length in bytes. Make a note of this, @@ -84,10 +84,15 @@ pub struct SequenceItem<'scale, 'resolver, R: TypeResolver> { item: ArrayItem<'scale, 'resolver, R>, } -impl<'scale, 'resolver, R: TypeResolver> Copy for SequenceItem<'scale, 'resolver, R> {} +impl<'scale, 'resolver, R> Copy for SequenceItem<'scale, 'resolver, R> +where + R: TypeResolver, + R::TypeId: Copy, +{ +} impl<'scale, 'resolver, R: TypeResolver> Clone for SequenceItem<'scale, 'resolver, R> { fn clone(&self) -> Self { - *self + SequenceItem { item: self.item.clone() } } } diff --git a/scale-decode/src/visitor/types/tuple.rs b/scale-decode/src/visitor/types/tuple.rs index f13c815..3faaaec 100644 --- a/scale-decode/src/visitor/types/tuple.rs +++ b/scale-decode/src/visitor/types/tuple.rs @@ -70,7 +70,7 @@ impl<'scale, 'resolver, R: TypeResolver> Tuple<'scale, 'resolver, R> { // Decode the bytes: let res = crate::visitor::decode_with_visitor_maybe_compact( b, - field.id, + field.id.clone(), self.types, visitor, self.is_compact, @@ -94,7 +94,7 @@ impl<'scale, 'resolver, R: TypeResolver> Iterator for Tuple<'scale, 'resolver, R type Item = Result, DecodeError>; fn next(&mut self) -> Option { // Record details we need before we decode and skip over the thing: - let field = *self.fields.get(self.next_field_idx)?; + let field = self.fields.get(self.next_field_idx)?.clone(); let num_bytes_before = self.item_bytes.len(); let item_bytes = self.item_bytes; @@ -120,7 +120,7 @@ impl<'scale, 'resolver, R: TypeResolver> Iterator for Tuple<'scale, 'resolver, R #[derive(Copy, Clone, Debug)] pub struct TupleField<'scale, 'resolver, R: TypeResolver> { bytes: &'scale [u8], - type_id: &'resolver R::TypeId, + type_id: R::TypeId, types: &'resolver R, is_compact: bool, } @@ -132,7 +132,7 @@ impl<'scale, 'resolver, R: TypeResolver> TupleField<'scale, 'resolver, R> { } /// The type ID associated with this field. pub fn type_id(&self) -> &R::TypeId { - self.type_id + &self.type_id } /// If the field is compact encoded pub fn is_compact(&self) -> bool { @@ -143,13 +143,18 @@ impl<'scale, 'resolver, R: TypeResolver> TupleField<'scale, 'resolver, R> { &self, visitor: V, ) -> Result, V::Error> { - crate::visitor::decode_with_visitor(&mut &*self.bytes, self.type_id, self.types, visitor) + crate::visitor::decode_with_visitor( + &mut &*self.bytes, + self.type_id.clone(), + self.types, + visitor, + ) } /// Decode this field into a specific type via [`DecodeAsType`]. pub fn decode_as_type(&self) -> Result { T::decode_as_type_maybe_compact( &mut &*self.bytes, - self.type_id, + self.type_id.clone(), self.types, self.is_compact, ) diff --git a/scale-decode/src/visitor/types/variant.rs b/scale-decode/src/visitor/types/variant.rs index 90b17dd..8c6232d 100644 --- a/scale-decode/src/visitor/types/variant.rs +++ b/scale-decode/src/visitor/types/variant.rs @@ -26,7 +26,7 @@ pub struct Variant<'scale, 'resolver, R: TypeResolver> { impl<'scale, 'resolver, R: TypeResolver> Variant<'scale, 'resolver, R> { pub(crate) fn new< - Fields: FieldIter<'resolver, R::TypeId> + 'resolver, + Fields: FieldIter<'resolver, R::TypeId>, Variants: VariantIter<'resolver, Fields>, >( bytes: &'scale [u8], @@ -41,7 +41,13 @@ impl<'scale, 'resolver, R: TypeResolver> Variant<'scale, 'resolver, R> { variants.find(|v| v.index == index).ok_or(DecodeError::VariantNotFound(index))?; // Allow decoding of the fields: - let fields = Composite::new(item_bytes, &mut variant.fields, types, false); + let fields = Composite::new( + core::iter::once(variant.name), + item_bytes, + &mut variant.fields, + types, + false, + ); Ok(Variant { bytes, variant_index: index, variant_name: variant.name, fields }) }