Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ The format is based on [Keep a Changelog].

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

## 0.16.1 - 2025-11-19

- Expose path information in sequences and variants, too, where possible.

## 0.16.0 - 2024-11-15

This release updates scale-bits to 0.7.0 which is exposed in the public API of scale-decode.
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.16.0"
version = "0.16.1"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "Apache-2.0"
Expand All @@ -18,5 +18,5 @@ include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"]
rust-version = "1.81.0"

[workspace.dependencies]
scale-decode = { version = "0.16.0", path = "scale-decode" }
scale-decode-derive = { version = "0.16.0", path = "scale-decode-derive" }
scale-decode = { version = "0.16.1", path = "scale-decode" }
scale-decode-derive = { version = "0.16.1", path = "scale-decode-derive" }
2 changes: 1 addition & 1 deletion scale-decode/src/error/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Context {
}

/// The current path that we're trying to encode.
pub struct Path<'a>(Cow<'a, Vec<Location>>);
pub struct Path<'a>(Cow<'a, [Location]>);

impl<'a> Path<'a> {
/// Cheaply convert the path to an owned version.
Expand Down
8 changes: 4 additions & 4 deletions scale-decode/src/visitor/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl<'temp, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver>
skip_decoding_and_return!(self, res, items)
}

fn visit_variant<Path, Fields, Var>(self, _path: Path, variants: Var) -> Self::Value
fn visit_variant<Path, Fields, Var>(self, path: Path, variants: Var) -> Self::Value
where
Path: PathIter<'resolver>,
Fields: FieldIter<'resolver, Self::TypeId>,
Expand All @@ -155,21 +155,21 @@ impl<'temp, 'scale, 'resolver, V: Visitor> ResolvedTypeVisitor<'resolver>
return Err(DecodeError::CannotDecodeCompactIntoType.into());
}

let mut variant = Variant::new(self.data, variants, self.types)?;
let mut variant = Variant::new(path, self.data, variants, self.types)?;
let res = self.visitor.visit_variant(&mut variant, self.type_id);

skip_decoding_and_return!(self, res, variant)
}

fn visit_sequence<Path>(self, _path: Path, inner_type_id: Self::TypeId) -> Self::Value
fn visit_sequence<Path>(self, path: Path, inner_type_id: Self::TypeId) -> Self::Value
where
Path: PathIter<'resolver>,
{
if self.is_compact {
return Err(DecodeError::CannotDecodeCompactIntoType.into());
}

let mut items = Sequence::new(self.data, inner_type_id, self.types)?;
let mut items = Sequence::new(path, self.data, inner_type_id, self.types)?;
let res = self.visitor.visit_sequence(&mut items, self.type_id);

skip_decoding_and_return!(self, res, items)
Expand Down
4 changes: 2 additions & 2 deletions scale-decode/src/visitor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ pub trait Visitor: Sized {
type TypeResolver: TypeResolver;

/// This method is called immediately upon running [`decode_with_visitor()`]. By default we ignore
/// this call and return our visitor back (ie [`DecodeAsTypeResult::Skipped(visitor)`]). If you choose to
/// do some decoding at this stage, return [`DecodeAsTypeResult::Decoded(result)`]. In either case, any bytes
/// this call and return our visitor back (ie [`DecodeAsTypeResult::Skipped`]). If you choose to
/// do some decoding at this stage, return [`DecodeAsTypeResult::Decoded`]. In either case, any bytes
/// that you consume from the input (by altering what it points to) will be consumed for any subsequent visiting.
///
/// # Warning
Expand Down
14 changes: 13 additions & 1 deletion scale-decode/src/visitor/types/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,32 @@ pub struct Sequence<'scale, 'resolver, R: TypeResolver> {
// The only thing we need to do otherwise is decode the compact encoded
// length from the beginning and keep track of the bytes including that.
values: Array<'scale, 'resolver, R>,
path: smallvec::SmallVec<[&'resolver str; 5]>,
}

impl<'scale, 'resolver, R: TypeResolver> Sequence<'scale, 'resolver, R> {
pub(crate) fn new(
path: impl Iterator<Item = &'resolver str>,
bytes: &'scale [u8],
type_id: R::TypeId,
types: &'resolver R,
) -> Result<Sequence<'scale, 'resolver, R>, DecodeError> {
let path = smallvec::SmallVec::from_iter(path);

// Sequences are prefixed with their length in bytes. Make a note of this,
// as well as the number of bytes
let item_bytes = &mut &*bytes;
let len = <Compact<u64>>::decode(item_bytes)?.0 as usize;

Ok(Sequence { bytes, values: Array::new(item_bytes, type_id, len, types) })
Ok(Sequence { path, bytes, values: Array::new(item_bytes, type_id, len, types) })
}
/// Return the name of the sequence type, if one was given.
pub fn name(&self) -> Option<&'resolver str> {
self.path.iter().last().copied()
}
/// Return the full path to the sequence type (including the name) if one was given.
pub fn path(&self) -> impl Iterator<Item = &'resolver str> + '_ {
self.path.iter().copied()
}
/// Skip over all bytes associated with this sequence. After calling this,
/// [`Self::bytes_from_undecoded()`] will represent the bytes after this sequence.
Expand Down
13 changes: 12 additions & 1 deletion scale-decode/src/visitor/types/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ pub struct Variant<'scale, 'resolver, R: TypeResolver> {
variant_name: &'resolver str,
variant_index: u8,
fields: Composite<'scale, 'resolver, R>,
path: smallvec::SmallVec<[&'resolver str; 5]>,
}

impl<'scale, 'resolver, R: TypeResolver> Variant<'scale, 'resolver, R> {
pub(crate) fn new<
Fields: FieldIter<'resolver, R::TypeId>,
Variants: VariantIter<'resolver, Fields>,
>(
path: impl Iterator<Item = &'resolver str>,
bytes: &'scale [u8],
mut variants: Variants,
types: &'resolver R,
) -> Result<Variant<'scale, 'resolver, R>, DecodeError> {
let path = smallvec::SmallVec::from_iter(path);
let index = *bytes.first().ok_or(DecodeError::NotEnoughInput)?;
let item_bytes = &bytes[1..];

Expand All @@ -49,11 +52,19 @@ impl<'scale, 'resolver, R: TypeResolver> Variant<'scale, 'resolver, R> {
false,
);

Ok(Variant { bytes, variant_index: index, variant_name: variant.name, fields })
Ok(Variant { path, bytes, variant_index: index, variant_name: variant.name, fields })
}
}

impl<'scale, 'resolver, R: TypeResolver> Variant<'scale, 'resolver, R> {
/// Return the name of the enum type that this variant belongs to, if one was given.
pub fn enum_name(&self) -> Option<&'resolver str> {
self.path.iter().last().copied()
}
/// Return the full path to the variant type (including the enum name) if one was given.
pub fn path(&self) -> impl Iterator<Item = &'resolver str> + '_ {
self.path.iter().copied()
}
/// Skip over all bytes associated with this variant. After calling this,
/// [`Self::bytes_from_undecoded()`] will represent the bytes after this variant.
pub fn skip_decoding(&mut self) -> Result<(), DecodeError> {
Expand Down
Loading