mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-13 02:15:50 +00:00
Introduce Metadata type (#974)
* WIP new Metadata type * Finish basic Metadata impl inc hashing and validation * remove caching from metadata; can add that higher up * remove caches * update retain to use Metadata * clippy fixes * update codegen to use Metadata * clippy * WIP fixing subxt lib * WIP fixing tests, rebuild artifacts, fix OrderedMap::retain * get --all-targets compiling * move DispatchError type lookup back to being optional * cargo clippy * fix docs * re-use VariantIndex to get variants * add docs and enforce docs on metadata crate * fix docs * add test and fix docs * cargo fmt * address review comments * update lockfiles * ExactSizeIter so we can ask for len() of things (and hopefully soon is_empty()
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use scale_info::{form::PortableForm, PortableRegistry, TypeDef, Variant};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Given some type ID and type registry, build a couple of
|
||||
/// indexes to look up variants by index or name. If the ID provided
|
||||
/// is not a variant, the index will be empty.
|
||||
///
|
||||
/// API optimized for dealing with the `Option<u32>` variant type IDs
|
||||
/// that we get in metadata pallets.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VariantIndex {
|
||||
by_name: HashMap<String, usize>,
|
||||
by_index: HashMap<u8, usize>,
|
||||
}
|
||||
|
||||
impl VariantIndex {
|
||||
/// Build indexes from the optional variant ID.
|
||||
pub fn build(variant_id: Option<u32>, types: &PortableRegistry) -> Self {
|
||||
let Some(variants) = Self::get(variant_id, types) else {
|
||||
return Self::empty()
|
||||
};
|
||||
|
||||
let mut by_name = HashMap::new();
|
||||
let mut by_index = HashMap::new();
|
||||
for (pos, variant) in variants.iter().enumerate() {
|
||||
by_name.insert(variant.name.to_owned(), pos);
|
||||
by_index.insert(variant.index, pos);
|
||||
}
|
||||
|
||||
Self { by_name, by_index }
|
||||
}
|
||||
|
||||
/// Build an empty index.
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
by_name: Default::default(),
|
||||
by_index: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the variants we're pointing at; None if this isn't possible.
|
||||
pub fn get(
|
||||
variant_id: Option<u32>,
|
||||
types: &PortableRegistry,
|
||||
) -> Option<&[Variant<PortableForm>]> {
|
||||
let Some(variant_id) = variant_id else {
|
||||
return None
|
||||
};
|
||||
let TypeDef::Variant(v) = &types.resolve(variant_id)?.type_def else {
|
||||
return None
|
||||
};
|
||||
Some(&v.variants)
|
||||
}
|
||||
|
||||
/// Lookup a variant by name; `None` if the type is not a variant or name isn't found.
|
||||
pub fn lookup_by_name<'a, K>(
|
||||
&self,
|
||||
name: &K,
|
||||
variant_id: Option<u32>,
|
||||
types: &'a PortableRegistry,
|
||||
) -> Option<&'a Variant<PortableForm>>
|
||||
where
|
||||
String: std::borrow::Borrow<K>,
|
||||
K: std::hash::Hash + Eq + ?Sized,
|
||||
{
|
||||
let pos = *self.by_name.get(name)?;
|
||||
let variants = Self::get(variant_id, types)?;
|
||||
variants.get(pos)
|
||||
}
|
||||
|
||||
/// Lookup a variant by index; `None` if the type is not a variant or index isn't found.
|
||||
pub fn lookup_by_index<'a>(
|
||||
&self,
|
||||
index: u8,
|
||||
variant_id: Option<u32>,
|
||||
types: &'a PortableRegistry,
|
||||
) -> Option<&'a Variant<PortableForm>> {
|
||||
let pos = *self.by_index.get(&index)?;
|
||||
let variants = Self::get(variant_id, types)?;
|
||||
variants.get(pos)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user