Releases: paritytech/scale-decode
v0.16.0
v0.15.0
0.15.0 - 2024-11-08
This release makes scale-decode entirely no_std
which is now using core::error::Error
instead of std::error::Error
as it was using before behind
the std feature
. Because of that the std feature
is now removed and the MSRV is bumped to 1.81.0.
v0.13.2
v0.13.0
0.13.0 - 2023-05-15
This minor release avoids a couple of panics in the case of invalid bytes being interpreted as BitVecs or strings.
A small API change was made to accommodate this, such that the Str::bytes_after
now returns a result rather than just the bytes.
Fixed
v0.12.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'svisit_composite()
method now exposes the name and path of the composite type being decoded, if one was provided.
v0.11.1
v0.11.0
0.11.0 - 2023-02-09
Up until now, this crate depended heavily on scale_info
to provide the type information that we used to drive our decoding of types. This release removes the explicit dependency on scale-info
, and instead depends on scale-type-resolver
, which offers a generic TypeResolver
trait whose implementations are able to provide the information needed to decode types (see this PR for more details). So now, the traits and types in scale-decode
have been made generic over which TypeResolver
is used to help decode things. scale-info::PortableRegistry
is one such implementation of TypeResolver
, and so can continue to be used in a similar way to before.
The main breaking changes are:
Visitor trait
The scale_decode::Visitor
trait now has an additional associated type, TypeResolver
.
The simplest change to recover the previous behaviour is to just continue to use scale_info::PortableRegistry
for this task, as was the case implicitly before:
struct MyVisitor;
impl Visitor for MyVisitor {
// ...
type TypeResolver = scale_info::PortableRegistry;
// ...
}
A better change is to make your Visitor
impls generic over what is used to resolve types unless you need a specific resolver:
struct MyVisitor<R>(PhantomData<R>);
impl <R> MyVisitor<R> {
pub fn new() -> Self {
Self(PhantomData)
}
}
impl <R: TypeResolver> Visitor for MyVisitor<R> {
// ...
type TypeResolver = R;
// ...
}
IntoVisitor trait
scale_decode::IntoVisitor
is implemented on all types that have an associated Visitor
that we can use to decode it. It used to look like this:
pub trait IntoVisitor {
type Visitor: for<'scale, 'resolver> visitor::Visitor<
Value<'scale, 'resolver> = Self,
Error = Error,
>;
fn into_visitor() -> Self::Visitor;
}
Now it looks like this:
pub trait IntoVisitor {
type AnyVisitor<R: TypeResolver>: for<'scale, 'resolver> visitor::Visitor<
Value<'scale, 'resolver> = Self,
Error = Error,
TypeResolver = R,
>;
fn into_visitor<R: TypeResolver>() -> Self::AnyVisitor<R>;
}
What this means is that if you want to implement IntoVisitor
for some type, then your Visitor
must be able to accept any valid TypeResolver
. This allows DecodeAsType
to also be generic over which TypeResolver
is provided.
DecodeAsType
This trait previously was specific to scale_info::PortableRegistry
and looked something like this:
pub trait DecodeAsType: Sized + IntoVisitor {
fn decode_as_type<R: TypeResolver>(
input: &mut &[u8],
type_id: u32,
types: &scale_info::PortableRegistry,
) -> Result<Self, Error> {
// ...
}
Now, it is generic over which type resolver to use (and as a side effect, requires a reference to the type_id
now, because it may not be Copy
any more):
pub trait DecodeAsType: Sized + IntoVisitor {
fn decode_as_type<R: TypeResolver>(
input: &mut &[u8],
type_id: &R::TypeId,
types: &R,
) -> Result<Self, Error> {
// ...
}
This is automatically implemented for all types which implement IntoVisitor
, as before.
Composite and Variant paths
Mostly, the changes just exist to make things generic over the TypeResolver
. One consequence of this is that Composite and Variant types no longer know their path, because currently TypeResolver
doesn't provide that information (since it's not necessary to the actual encoding/decoding of types). If there is demand for this, we can consider allowing TypeResolver
impls to optionally provide these extra details.
v0.10.0
0.10.0 - 2023-11-10
This release changes IntoVisitor
to require that the corresponding Visitor
implements scale_decode::Error
, rather than allowing the error to be anything that can be converted into a scale_decode::Error
. This has the following advantages:
- It makes
DecodeAsType
a proper super-trait ofIntoVisitor
, meaning it can be used anywhereIntoVisitor
is. Previously, usingDecodeAsType
in some places also required that you add a bound likeB: IntoVisitor, <B::Visitor as Visitor>::Error: Into<scale_decode::Error
, ie theError
type needed to explicitly be declared as convertible in the way thatDecodeAsType
requires. - It simplifies the code.
- It makes it a bit easier to understand how to correctly make a type implement
DecodeAsType
.
The main drawback is that if your Visitor
implementation doesn't have Error = scale_decode::Error
, then it can no longer be used with IntoVisitor
. To work around this, a new adapter type, scale_decode::visitor::VisitorWithCrateError(your_visitor)
has been added; any visitor wrapped in this type whose error implements Into<scale_decode::Error>
will now implement Visitor
with Error = scale_decode::Error
.
v0.9.0
0.9.0 - 2023-08-02
- Change how compact encoding is handled:
visit_compact_*
functions are removed from theVisitor
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). - Improve custom error handling: custom errors now require
Debug + Display
onno_std
orError
onstd
.
Error::custom()
now accepts anything implementing these traits rather than depending onInto<Error>
(#31).