Skip to content

Commit d49d35b

Browse files
authored
Prep to release 0.12.1: add map_ids fns in a few places to simplify TypeId converting (#60)
* Add map_ids fns in a few places to simplify converting the TypeId * Prep for 0.12.1 release
1 parent cae4397 commit d49d35b

File tree

6 files changed

+108
-5
lines changed

6 files changed

+108
-5
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ The format is based on [Keep a Changelog].
44

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

7+
## 0.12.1 (2025-11-12)
8+
9+
- Add `map_ids()` functions to `RuntimeApiInfo`, `StorageInfo` and `ViewFunctionInfo` to make translating the `TypeId` parameter simpler.
10+
This adds a `'static` bound to `StorageInfo` type IDs, but it is not expected that this will break anything as this is already the case for `u32` and `LookupName` IDs (and is required in many other places).
11+
712
## 0.12.0 (2025-11-10)
813

914
- Bump to scale-info-legacy 0.3.0.

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "frame-decode"
3-
version = "0.12.0"
3+
version = "0.12.1"
44
edition = "2024"
55
description = "Decode extrinsics and storage from Substrate based chains"
66
license = "Apache-2.0"

src/methods/runtime_api_type_info.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use super::Entry;
1717
use crate::utils::Either;
1818
use alloc::borrow::Cow;
1919
use alloc::borrow::ToOwned;
20-
use alloc::string::String;
20+
use alloc::string::{String, ToString};
21+
use alloc::vec::Vec;
2122

2223
/// This can be implemented for anything capable of providing Runtime API type information.
2324
/// It is implemented for newer versions of frame-metadata (V15 and above).
@@ -93,6 +94,42 @@ impl<'info, TypeId: Clone + 'static> RuntimeApiInfo<'info, TypeId> {
9394
output_id: self.output_id,
9495
}
9596
}
97+
98+
/// Map the type IDs in this [`RuntimeApiInfo`], returning a new one or bailing early with an error if something goes wrong.
99+
/// This also takes ownership of the [`RuntimeApiInfo`], turning the lifetime to static.
100+
pub fn map_ids<NewTypeId: Clone, E, F: FnMut(TypeId) -> Result<NewTypeId, E>>(
101+
self,
102+
mut f: F,
103+
) -> Result<RuntimeApiInfo<'static, NewTypeId>, E> {
104+
let new_output_id = f(self.output_id)?;
105+
let mut new_inputs = Vec::with_capacity(self.inputs.len());
106+
107+
match self.inputs {
108+
Cow::Borrowed(inputs) => {
109+
for input in inputs {
110+
new_inputs.push(RuntimeApiInput {
111+
// We always have to allocate if inputs is borrowed:
112+
name: Cow::Owned(input.name.to_string()),
113+
id: f(input.id.clone())?,
114+
});
115+
}
116+
}
117+
Cow::Owned(inputs) => {
118+
for input in inputs {
119+
new_inputs.push(RuntimeApiInput {
120+
// If inputs is owned, we only allocate if name is borrowed:
121+
name: Cow::Owned(input.name.into_owned()),
122+
id: f(input.id.clone())?,
123+
});
124+
}
125+
}
126+
}
127+
128+
Ok(RuntimeApiInfo {
129+
inputs: Cow::Owned(new_inputs),
130+
output_id: new_output_id,
131+
})
132+
}
96133
}
97134

98135
/// Information about a specific input value to a Runtime API.

src/methods/storage_type_info.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ pub struct StorageInfo<'info, TypeId: Clone> {
131131
pub default_value: Option<Cow<'info, [u8]>>,
132132
}
133133

134-
impl<'info, TypeId: Clone> StorageInfo<'info, TypeId> {
134+
impl<'info, TypeId: Clone + 'static> StorageInfo<'info, TypeId> {
135135
/// Take ownership of this [`StorageInfo`], turning any lifetimes to `'static`.
136136
pub fn into_owned(self) -> StorageInfo<'static, TypeId> {
137137
StorageInfo {
@@ -140,6 +140,29 @@ impl<'info, TypeId: Clone> StorageInfo<'info, TypeId> {
140140
default_value: self.default_value.map(|v| Cow::Owned(v.into_owned())),
141141
}
142142
}
143+
144+
/// Map the type IDs in this [`StorageInfo`], returning a new one or bailing early with an error if something goes wrong.
145+
/// This also takes ownership of the [`StorageInfo`], turning the lifetime to static.
146+
pub fn map_ids<NewTypeId: Clone, E, F: FnMut(TypeId) -> Result<NewTypeId, E>>(
147+
self,
148+
mut f: F,
149+
) -> Result<StorageInfo<'static, NewTypeId>, E> {
150+
let new_value_id = f(self.value_id)?;
151+
let mut new_keys = Vec::with_capacity(self.keys.len());
152+
153+
for k in self.keys.iter() {
154+
new_keys.push(StorageKeyInfo {
155+
hasher: k.hasher,
156+
key_id: f(k.key_id.clone())?,
157+
});
158+
}
159+
160+
Ok(StorageInfo {
161+
keys: Cow::Owned(new_keys),
162+
value_id: new_value_id,
163+
default_value: self.default_value.map(|d| Cow::Owned(d.into_owned())),
164+
})
165+
}
143166
}
144167

145168
/// Information about a single key within a storage entry.

src/methods/view_function_type_info.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use super::Entry;
1717
use crate::utils::Either;
1818
use alloc::borrow::Cow;
1919
use alloc::borrow::ToOwned;
20-
use alloc::string::String;
20+
use alloc::string::{String, ToString};
21+
use alloc::vec::Vec;
2122

2223
/// This is implemented for anything capable of providing information about view functions
2324
/// (primarily metadata V16 and onwards).
@@ -96,6 +97,43 @@ impl<'info, TypeId: Clone> ViewFunctionInfo<'info, TypeId> {
9697
output_id: self.output_id,
9798
}
9899
}
100+
101+
/// Map the type IDs in this [`ViewFunctionInfo`], returning a new one or bailing early with an error if something goes wrong.
102+
/// This also takes ownership of the [`ViewFunctionInfo`], turning the lifetime to static.
103+
pub fn map_ids<NewTypeId: Clone, E, F: FnMut(TypeId) -> Result<NewTypeId, E>>(
104+
self,
105+
mut f: F,
106+
) -> Result<ViewFunctionInfo<'static, NewTypeId>, E> {
107+
let new_output_id = f(self.output_id)?;
108+
let mut new_inputs = Vec::with_capacity(self.inputs.len());
109+
110+
match self.inputs {
111+
Cow::Borrowed(inputs) => {
112+
for input in inputs {
113+
new_inputs.push(ViewFunctionInput {
114+
// We always have to allocate if inputs is borrowed:
115+
name: Cow::Owned(input.name.to_string()),
116+
id: f(input.id.clone())?,
117+
});
118+
}
119+
}
120+
Cow::Owned(inputs) => {
121+
for input in inputs {
122+
new_inputs.push(ViewFunctionInput {
123+
// If inputs is owned, we only allocate if name is borrowed:
124+
name: Cow::Owned(input.name.into_owned()),
125+
id: f(input.id.clone())?,
126+
});
127+
}
128+
}
129+
}
130+
131+
Ok(ViewFunctionInfo {
132+
query_id: self.query_id,
133+
inputs: Cow::Owned(new_inputs),
134+
output_id: new_output_id,
135+
})
136+
}
99137
}
100138

101139
/// Information about a specific input value to a View Function.

0 commit comments

Comments
 (0)