diff --git a/CHANGELOG.md b/CHANGELOG.md index 8629a69..dae59ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,14 @@ The format is based on [Keep a Changelog]. [Keep a Changelog]: http://keepachangelog.com/en/1.0.0/ -## 0.9.0 - 2023-07-28 +## 0.9.0 - 2023-08-02 +- Change how compact encoding is handled: `visit_compact_*` functions are removed from the `Visitor` trait, and + compact encoding is now handled recursively and should now work in more cases (such as nested structs with compact + encoded values inside) ([#32](https://github.com/paritytech/scale-decode/pull/32)). - Improve custom error handling: custom errors now require `Debug + Display` on `no_std` or `Error` on `std`. - `Error::custom()` now accepts anything implementing these traits rather than depending on `Into`. + `Error::custom()` now accepts anything implementing these traits rather than depending on `Into` + ([#31](https://github.com/paritytech/scale-decode/pull/31)). ## 0.8.0 diff --git a/README.md b/README.md index ec19660..314322b 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,11 @@ generated. Here's an example of implementing `Visitor` to decode bytes into a custom `Value` type: ```rust -use scale_decode::visitor::{self, TypeId}; +use scale_decode::visitor::{ + self, + types::{Array, BitSequence, Composite, Sequence, Str, Tuple, Variant}, + TypeId, +}; // A custom type we'd like to decode into: #[derive(Debug, PartialEq)] @@ -40,11 +44,6 @@ enum Value { I64(i64), I128(i128), I256([u8; 32]), - CompactU8(u8), - CompactU16(u16), - CompactU32(u32), - CompactU64(u64), - CompactU128(u128), Sequence(Vec), Composite(Vec<(String, Value)>), Tuple(Vec), @@ -58,147 +57,112 @@ enum Value { // values into this type: struct ValueVisitor; impl visitor::Visitor for ValueVisitor { - type Value<'scale> = Value; + type Value<'scale, 'info> = Value; type Error = visitor::DecodeError; - fn visit_bool<'scale>( + fn visit_bool<'scale, 'info>( self, value: bool, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::Bool(value)) } - fn visit_char<'scale>( + fn visit_char<'scale, 'info>( self, value: char, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::Char(value)) } - fn visit_u8<'scale>( + fn visit_u8<'scale, 'info>( self, value: u8, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U8(value)) } - fn visit_u16<'scale>( + fn visit_u16<'scale, 'info>( self, value: u16, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U16(value)) } - fn visit_u32<'scale>( + fn visit_u32<'scale, 'info>( self, value: u32, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U32(value)) } - fn visit_u64<'scale>( + fn visit_u64<'scale, 'info>( self, value: u64, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U64(value)) } - fn visit_u128<'scale>( + fn visit_u128<'scale, 'info>( self, value: u128, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U128(value)) } - fn visit_u256( + fn visit_u256<'info>( self, value: &'_ [u8; 32], _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U256(*value)) } - fn visit_i8<'scale>( + fn visit_i8<'scale, 'info>( self, value: i8, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I8(value)) } - fn visit_i16<'scale>( + fn visit_i16<'scale, 'info>( self, value: i16, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I16(value)) } - fn visit_i32<'scale>( + fn visit_i32<'scale, 'info>( self, value: i32, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I32(value)) } - fn visit_i64<'scale>( + fn visit_i64<'scale, 'info>( self, value: i64, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I64(value)) } - fn visit_i128<'scale>( + fn visit_i128<'scale, 'info>( self, value: i128, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I128(value)) } - fn visit_i256( + fn visit_i256<'info>( self, value: &'_ [u8; 32], _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I256(*value)) } - fn visit_compact_u8<'scale>( + fn visit_sequence<'scale, 'info>( self, - value: Compact, + value: &mut Sequence<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU8(value.value())) - } - fn visit_compact_u16<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU16(value.value())) - } - fn visit_compact_u32<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU32(value.value())) - } - fn visit_compact_u64<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU64(value.value())) - } - fn visit_compact_u128<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU128(value.value())) - } - fn visit_sequence<'scale>( - self, - value: &mut Sequence<'scale, '_>, - _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor) { let val = val?; @@ -206,11 +170,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Sequence(vals)) } - fn visit_composite<'scale>( + fn visit_composite<'scale, 'info>( self, - value: &mut Composite<'scale, '_>, + value: &mut Composite<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; for item in value.by_ref() { let item = item?; @@ -220,11 +184,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Composite(vals)) } - fn visit_tuple<'scale>( + fn visit_tuple<'scale, 'info>( self, - value: &mut Tuple<'scale, '_>, + value: &mut Tuple<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor) { let val = val?; @@ -232,18 +196,18 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Tuple(vals)) } - fn visit_str<'scale>( + fn visit_str<'scale, 'info>( self, value: &mut Str<'scale>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::Str(value.as_str()?.to_owned())) } - fn visit_variant<'scale>( + fn visit_variant<'scale, 'info>( self, - value: &mut Variant<'scale, '_>, + value: &mut Variant<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; let fields = value.fields(); for item in fields.by_ref() { @@ -254,11 +218,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Variant(value.name().to_owned(), vals)) } - fn visit_array<'scale>( + fn visit_array<'scale, 'info>( self, - value: &mut Array<'scale, '_>, + value: &mut Array<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor) { let val = val?; @@ -266,11 +230,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Array(vals)) } - fn visit_bitsequence<'scale>( + fn visit_bitsequence<'scale, 'info>( self, value: &mut BitSequence<'scale>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let bools: Result = value.decode()?.collect(); Ok(Value::BitSequence(bools?)) } @@ -306,5 +270,5 @@ use scale_decode::DecodeAsType; let value = Value::decode_as_type(scale_bytes, type_id, types)?; ``` -With an `IntoVisitor` impl, you'd also benefit from being able to decode things like `Vec`, `(Value, bool)`, `Arc` -and so on in the same way. \ No newline at end of file +With an `IntoVisitor` impl, you'd also benefit from being able to decode things like `Vec`, +`(Value, bool)`, `Arc` and so on in the same way. \ No newline at end of file diff --git a/scale-decode/README.md b/scale-decode/README.md index ec19660..314322b 100644 --- a/scale-decode/README.md +++ b/scale-decode/README.md @@ -21,7 +21,11 @@ generated. Here's an example of implementing `Visitor` to decode bytes into a custom `Value` type: ```rust -use scale_decode::visitor::{self, TypeId}; +use scale_decode::visitor::{ + self, + types::{Array, BitSequence, Composite, Sequence, Str, Tuple, Variant}, + TypeId, +}; // A custom type we'd like to decode into: #[derive(Debug, PartialEq)] @@ -40,11 +44,6 @@ enum Value { I64(i64), I128(i128), I256([u8; 32]), - CompactU8(u8), - CompactU16(u16), - CompactU32(u32), - CompactU64(u64), - CompactU128(u128), Sequence(Vec), Composite(Vec<(String, Value)>), Tuple(Vec), @@ -58,147 +57,112 @@ enum Value { // values into this type: struct ValueVisitor; impl visitor::Visitor for ValueVisitor { - type Value<'scale> = Value; + type Value<'scale, 'info> = Value; type Error = visitor::DecodeError; - fn visit_bool<'scale>( + fn visit_bool<'scale, 'info>( self, value: bool, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::Bool(value)) } - fn visit_char<'scale>( + fn visit_char<'scale, 'info>( self, value: char, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::Char(value)) } - fn visit_u8<'scale>( + fn visit_u8<'scale, 'info>( self, value: u8, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U8(value)) } - fn visit_u16<'scale>( + fn visit_u16<'scale, 'info>( self, value: u16, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U16(value)) } - fn visit_u32<'scale>( + fn visit_u32<'scale, 'info>( self, value: u32, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U32(value)) } - fn visit_u64<'scale>( + fn visit_u64<'scale, 'info>( self, value: u64, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U64(value)) } - fn visit_u128<'scale>( + fn visit_u128<'scale, 'info>( self, value: u128, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U128(value)) } - fn visit_u256( + fn visit_u256<'info>( self, value: &'_ [u8; 32], _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::U256(*value)) } - fn visit_i8<'scale>( + fn visit_i8<'scale, 'info>( self, value: i8, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I8(value)) } - fn visit_i16<'scale>( + fn visit_i16<'scale, 'info>( self, value: i16, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I16(value)) } - fn visit_i32<'scale>( + fn visit_i32<'scale, 'info>( self, value: i32, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I32(value)) } - fn visit_i64<'scale>( + fn visit_i64<'scale, 'info>( self, value: i64, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I64(value)) } - fn visit_i128<'scale>( + fn visit_i128<'scale, 'info>( self, value: i128, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I128(value)) } - fn visit_i256( + fn visit_i256<'info>( self, value: &'_ [u8; 32], _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::I256(*value)) } - fn visit_compact_u8<'scale>( + fn visit_sequence<'scale, 'info>( self, - value: Compact, + value: &mut Sequence<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU8(value.value())) - } - fn visit_compact_u16<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU16(value.value())) - } - fn visit_compact_u32<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU32(value.value())) - } - fn visit_compact_u64<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU64(value.value())) - } - fn visit_compact_u128<'scale>( - self, - value: Compact, - _type_id: TypeId, - ) -> Result, Self::Error> { - Ok(Value::CompactU128(value.value())) - } - fn visit_sequence<'scale>( - self, - value: &mut Sequence<'scale, '_>, - _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor) { let val = val?; @@ -206,11 +170,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Sequence(vals)) } - fn visit_composite<'scale>( + fn visit_composite<'scale, 'info>( self, - value: &mut Composite<'scale, '_>, + value: &mut Composite<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; for item in value.by_ref() { let item = item?; @@ -220,11 +184,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Composite(vals)) } - fn visit_tuple<'scale>( + fn visit_tuple<'scale, 'info>( self, - value: &mut Tuple<'scale, '_>, + value: &mut Tuple<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor) { let val = val?; @@ -232,18 +196,18 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Tuple(vals)) } - fn visit_str<'scale>( + fn visit_str<'scale, 'info>( self, value: &mut Str<'scale>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { Ok(Value::Str(value.as_str()?.to_owned())) } - fn visit_variant<'scale>( + fn visit_variant<'scale, 'info>( self, - value: &mut Variant<'scale, '_>, + value: &mut Variant<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; let fields = value.fields(); for item in fields.by_ref() { @@ -254,11 +218,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Variant(value.name().to_owned(), vals)) } - fn visit_array<'scale>( + fn visit_array<'scale, 'info>( self, - value: &mut Array<'scale, '_>, + value: &mut Array<'scale, 'info>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let mut vals = vec![]; while let Some(val) = value.decode_item(ValueVisitor) { let val = val?; @@ -266,11 +230,11 @@ impl visitor::Visitor for ValueVisitor { } Ok(Value::Array(vals)) } - fn visit_bitsequence<'scale>( + fn visit_bitsequence<'scale, 'info>( self, value: &mut BitSequence<'scale>, _type_id: TypeId, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let bools: Result = value.decode()?.collect(); Ok(Value::BitSequence(bools?)) } @@ -306,5 +270,5 @@ use scale_decode::DecodeAsType; let value = Value::decode_as_type(scale_bytes, type_id, types)?; ``` -With an `IntoVisitor` impl, you'd also benefit from being able to decode things like `Vec`, `(Value, bool)`, `Arc` -and so on in the same way. \ No newline at end of file +With an `IntoVisitor` impl, you'd also benefit from being able to decode things like `Vec`, +`(Value, bool)`, `Arc` and so on in the same way. \ No newline at end of file