Skip to content

Commit

Permalink
Bump to scale-type-resolver 0.2 and prep for 0.7 release (#21)
Browse files Browse the repository at this point in the history
* Changes for scale-type-resolver 0.2

* Bump to 0.7 to prepare for release

* clippy
  • Loading branch information
jsdw authored Apr 29, 2024
1 parent b9e12c5 commit 2f47620
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 158 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ The format is based on [Keep a Changelog].

[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/

## [v0.7.0] - 2024-04-29

Update the `scale-type-resolver` dependency to 0.2.0 (and bump `scale-bits` for the same reason).

The main change here is that type IDs are now passed by value, rather than reference.

## [v0.6.0] - 2024-02-16

Up until now, `scale-info` has been the library that gives us the information needed to know how to SCALE encode values to the correct shape. In this release, we remove it from our dependency tree and replace it with `scale-type-resolver`, which provides a generic `TypeResolver` trait whose implementations are able to provide the information needed to encode/decode types. So now, rather than taking in a `scale_info::PortableRegistry`, the `EncodeAsType` and `EncodeAsFields` traits take a generic `R: scale_type_resolver::TypeResolver` value. `scale_info::PortableRegistry` implements `TypeResolver`, and so it can continue to be used similarly to before (though now, `type_id` is passed as a reference), but now we are generic over where the type information we need comes from.
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.6.0"
version = "0.7.0"
authors = ["Parity Technologies <[email protected]>"]
edition = "2021"
license = "Apache-2.0"
Expand All @@ -17,5 +17,5 @@ keywords = ["parity", "scale", "encoding"]
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"]

[workspace.dependencies]
scale-encode = { version = "0.6.0", path = "scale-encode" }
scale-encode-derive = { version = "0.6.0", path = "scale-encode-derive" }
scale-encode = { version = "0.7.0", path = "scale-encode" }
scale-encode-derive = { version = "0.7.0", path = "scale-encode-derive" }
4 changes: 2 additions & 2 deletions scale-encode-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn generate_enum_impl(
fn encode_as_type_to<ScaleEncodeResolver: #path_to_scale_encode::TypeResolver>(
&self,
// long variable names to prevent conflict with struct field names:
__encode_as_type_type_id: &ScaleEncodeResolver::TypeId,
__encode_as_type_type_id: ScaleEncodeResolver::TypeId,
__encode_as_type_types: &ScaleEncodeResolver,
__encode_as_type_out: &mut #path_to_scale_encode::Vec<u8>
) -> Result<(), #path_to_scale_encode::Error> {
Expand Down Expand Up @@ -115,7 +115,7 @@ fn generate_struct_impl(
fn encode_as_type_to<ScaleEncodeResolver: #path_to_scale_encode::TypeResolver>(
&self,
// long variable names to prevent conflict with struct field names:
__encode_as_type_type_id: &ScaleEncodeResolver::TypeId,
__encode_as_type_type_id: ScaleEncodeResolver::TypeId,
__encode_as_type_types: &ScaleEncodeResolver,
__encode_as_type_out: &mut #path_to_scale_encode::Vec<u8>
) -> Result<(), #path_to_scale_encode::Error> {
Expand Down
6 changes: 3 additions & 3 deletions scale-encode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ bits = ["dep:scale-bits"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
scale-type-resolver = { version = "0.1.1", default-features = false, features = ["visitor"] }
scale-bits = { version = "0.5.0", default-features = false, optional = true }
scale-type-resolver = { version = "0.2.0", default-features = false, features = ["visitor"] }
scale-bits = { version = "0.6.0", default-features = false, optional = true }
scale-encode-derive = { workspace = true, optional = true }
primitive-types = { version = "0.12.0", optional = true, default-features = false }
smallvec = "1.10.0"
Expand All @@ -45,4 +45,4 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features =
trybuild = "1.0.72"
# enable scale-info feature for testing:
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"] }
17 changes: 9 additions & 8 deletions scale-encode/src/impls/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ use scale_type_resolver::{visitor, TypeResolver};
impl EncodeAsType for scale_bits::Bits {
fn encode_as_type_to<R: TypeResolver>(
&self,
type_id: &R::TypeId,
type_id: R::TypeId,
types: &R,
out: &mut Vec<u8>,
) -> Result<(), crate::Error> {
let type_id = super::find_single_entry_with_same_repr(type_id, types);

let v = visitor::new(out, |_, _| Err(wrong_shape(type_id))).visit_bit_sequence(
|out, store, order| {
let format = scale_bits::Format { store, order };
scale_bits::encode_using_format_to(self.iter(), format, out);
Ok(())
},
);
let v = visitor::new((type_id.clone(), out), |(type_id, _out), _| {
Err(wrong_shape(type_id))
})
.visit_bit_sequence(|(_type_id, out), store, order| {
let format = scale_bits::Format { store, order };
scale_bits::encode_using_format_to(self.iter(), format, out);
Ok(())
});

super::resolve_type_and_encode(types, type_id, v)
}
Expand Down
72 changes: 37 additions & 35 deletions scale-encode/src/impls/composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ use scale_type_resolver::visitor;
trait EncodeAsTypeWithResolver<R: TypeResolver> {
fn encode_as_type_with_resolver_to(
&self,
type_id: &R::TypeId,
type_id: R::TypeId,
types: &R,
out: &mut Vec<u8>,
) -> Result<(), Error>;
}
impl<T: EncodeAsType, R: TypeResolver> EncodeAsTypeWithResolver<R> for T {
fn encode_as_type_with_resolver_to(
&self,
type_id: &R::TypeId,
type_id: R::TypeId,
types: &R,
out: &mut Vec<u8>,
) -> Result<(), Error> {
Expand Down Expand Up @@ -73,7 +73,7 @@ impl<'a, R: TypeResolver> CompositeField<'a, R> {
/// SCALE encode this composite field to bytes based on the underlying type.
pub fn encode_composite_field_to(
&self,
type_id: &R::TypeId,
type_id: R::TypeId,
types: &R,
out: &mut Vec<u8>,
) -> Result<(), Error> {
Expand All @@ -99,7 +99,7 @@ impl<'a, R: TypeResolver> CompositeField<'a, R> {
/// impl EncodeAsType for MyType {
/// fn encode_as_type_to<R: TypeResolver>(
/// &self,
/// type_id: &R::TypeId,
/// type_id: R::TypeId,
/// types: &R,
/// out: &mut Vec<u8>
/// ) -> Result<(), Error> {
Expand Down Expand Up @@ -150,7 +150,7 @@ where
/// allocates a [`Vec`] and returns it.
pub fn encode_composite_as_type(
&self,
type_id: &R::TypeId,
type_id: R::TypeId,
types: &R,
) -> Result<Vec<u8>, Error> {
let mut out = Vec::new();
Expand All @@ -161,7 +161,7 @@ where
/// Encode this composite value as the provided type to the output bytes.
pub fn encode_composite_as_type_to(
&self,
type_id: &R::TypeId,
type_id: R::TypeId,
types: &R,
out: &mut Vec<u8>,
) -> Result<(), Error> {
Expand All @@ -172,27 +172,32 @@ where
// are names, we may want to line up input field(s) on them.
let type_id = skip_through_single_unnamed_fields(type_id, types);

let v = visitor::new((out, vals_iter), |(out, mut vals_iter), _| {
// Rather than immediately giving up, we should at least see whether
// we can skip one level in to our value and encode that.
if vals_iter_len == 1 {
return vals_iter
.next()
.expect("1 value expected")
.1
.encode_composite_field_to(type_id, types, out);
}
let v = visitor::new(
(type_id.clone(), out, vals_iter),
|(type_id, out, mut vals_iter), _| {
// Rather than immediately giving up, we should at least see whether
// we can skip one level in to our value and encode that.
if vals_iter_len == 1 {
return vals_iter
.next()
.expect("1 value expected")
.1
.encode_composite_field_to(type_id, types, out);
}

// If we get here, then it means the value we were given had more than
// one field, and the type we were given was ultimately some one-field thing
// that contained a non composite/tuple type, so it would never work out.
Err(Error::new(ErrorKind::WrongShape {
actual: Kind::Struct,
expected_id: format!("{type_id:?}"),
}))
// If we get here, then it means the value we were given had more than
// one field, and the type we were given was ultimately some one-field thing
// that contained a non composite/tuple type, so it would never work out.
Err(Error::new(ErrorKind::WrongShape {
actual: Kind::Struct,
expected_id: format!("{type_id:?}"),
}))
},
)
.visit_not_found(|(type_id, _, _)| {
Err(Error::new(ErrorKind::TypeNotFound(format!("{type_id:?}"))))
})
.visit_not_found(|_| Err(Error::new(ErrorKind::TypeNotFound(format!("{type_id:?}")))))
.visit_composite(|(out, mut vals_iter), mut fields| {
.visit_composite(|(type_id, out, mut vals_iter), _, mut fields| {
// If vals are named, we may need to line them up with some named composite.
// If they aren't named, we only care about lining up based on matching lengths.
let is_named_vals = vals_iter.clone().any(|(name, _)| name.is_some());
Expand All @@ -209,7 +214,7 @@ where

self.encode_composite_fields_to(&mut fields, types, out)
})
.visit_tuple(|(out, mut vals_iter), type_ids| {
.visit_tuple(|(type_id, out, mut vals_iter), type_ids| {
// If there is exactly one val, it won't line up with the tuple then, so
// try encoding one level in instead.
if vals_iter_len == 1 {
Expand Down Expand Up @@ -301,7 +306,7 @@ where
}

for (idx, (field, (name, val))) in fields.iter().zip(vals_iter).enumerate() {
val.encode_composite_field_to(field.id, types, out)
val.encode_composite_field_to(field.id.clone(), types, out)
.map_err(|e| {
let loc = if let Some(name) = name {
Location::field(name.to_string())
Expand All @@ -318,12 +323,9 @@ where

// Single unnamed fields carry no useful information and can be skipped through.
// Single named fields may still be useful to line up with named composites.
fn skip_through_single_unnamed_fields<'a, R: TypeResolver>(
type_id: &'a R::TypeId,
types: &'a R,
) -> &'a R::TypeId {
let v = visitor::new((), |_, _| type_id)
.visit_composite(|_, fields| {
fn skip_through_single_unnamed_fields<R: TypeResolver>(type_id: R::TypeId, types: &R) -> R::TypeId {
let v = visitor::new(type_id.clone(), |type_id, _| type_id)
.visit_composite(|type_id, _, fields| {
// If exactly 1 unnamed field, recurse into it, else return current type ID.
let Some(f) = fields.next() else {
return type_id;
Expand All @@ -333,7 +335,7 @@ fn skip_through_single_unnamed_fields<'a, R: TypeResolver>(
};
skip_through_single_unnamed_fields(f.id, types)
})
.visit_tuple(|_, type_ids| {
.visit_tuple(|type_id, type_ids| {
// Else if exactly 1 tuple entry, recurse into it, else return current type ID.
let Some(new_type_id) = type_ids.next() else {
return type_id;
Expand All @@ -344,5 +346,5 @@ fn skip_through_single_unnamed_fields<'a, R: TypeResolver>(
skip_through_single_unnamed_fields(new_type_id, types)
});

types.resolve_type(type_id, v).unwrap_or(type_id)
types.resolve_type(type_id.clone(), v).unwrap_or(type_id)
}
Loading

0 comments on commit 2f47620

Please sign in to comment.