mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 13:31:10 +00:00
Make the codegen more accessible for running in WASM (#1154)
* minor api changes * parsing instead of format_ident! * fix self issue * expose types on typegen * web wasm support via feature flag * fmt and clippy * small adjustments * remove exposing of types() in type generator * adjust compile error * remove little any flag * Need access to the type registry from the typegen again * Bump proc-macro2 from 1.0.66 to 1.0.67 (#1164) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.66 to 1.0.67. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.66...1.0.67) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump serde_json from 1.0.106 to 1.0.107 (#1166) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.106 to 1.0.107. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.106...v1.0.107) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump trybuild from 1.0.84 to 1.0.85 (#1167) Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.84 to 1.0.85. - [Release notes](https://github.com/dtolnay/trybuild/releases) - [Commits](https://github.com/dtolnay/trybuild/compare/1.0.84...1.0.85) --- updated-dependencies: - dependency-name: trybuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump Swatinem/rust-cache from 2.6.2 to 2.7.0 (#1168) Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.6.2 to 2.7.0. - [Release notes](https://github.com/swatinem/rust-cache/releases) - [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md) - [Commits](https://github.com/swatinem/rust-cache/compare/e207df5d269b42b69c8bc5101da26f7d31feddb4...a95ba195448af2da9b00fb742d14ffaaf3c21f43) --- updated-dependencies: - dependency-name: Swatinem/rust-cache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump jsonrpsee from 0.20.0 to 0.20.1 (#1165) Bumps [jsonrpsee](https://github.com/paritytech/jsonrpsee) from 0.20.0 to 0.20.1. - [Release notes](https://github.com/paritytech/jsonrpsee/releases) - [Changelog](https://github.com/paritytech/jsonrpsee/blob/v0.20.1/CHANGELOG.md) - [Commits](https://github.com/paritytech/jsonrpsee/compare/v0.20.0...v0.20.1) --- updated-dependencies: - dependency-name: jsonrpsee dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump clap from 4.4.2 to 4.4.3 (#1163) Bumps [clap](https://github.com/clap-rs/clap) from 4.4.2 to 4.4.3. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.2...v4.4.3) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix double quote import introduced by merge * clippy * put ensure_unique_types on metadata, revert toml changes * fmt * solve frame_metadata import * tidy fetch-metadata and non_exhaustive on errors * remove the getrandom thing * fix toml autoformatting --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
+7
-43
@@ -20,14 +20,14 @@ use crate::error::CodegenError;
|
||||
use crate::{
|
||||
ir,
|
||||
types::{CompositeDef, CompositeDefFields, TypeGenerator, TypeSubstitutes},
|
||||
utils::{fetch_metadata_bytes_blocking, MetadataVersion, Url},
|
||||
CratePath,
|
||||
};
|
||||
|
||||
use codec::Decode;
|
||||
use heck::ToSnakeCase as _;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
use std::{collections::HashMap, fs, io::Read, path, string::ToString};
|
||||
use std::{fs, io::Read, path, string::ToString};
|
||||
use syn::parse_quote;
|
||||
|
||||
/// Generate the runtime API for interacting with a substrate runtime.
|
||||
@@ -146,7 +146,10 @@ impl GenerateRuntimeApi {
|
||||
/// # Warning
|
||||
///
|
||||
/// Not recommended to be used in production environments.
|
||||
pub fn generate_from_url(self, url: Url) -> Result<TokenStream2, CodegenError> {
|
||||
#[cfg(feature = "fetch-metadata")]
|
||||
pub fn generate_from_url(self, url: crate::utils::Url) -> Result<TokenStream2, CodegenError> {
|
||||
use crate::utils::{fetch_metadata_bytes_blocking, MetadataVersion, Url};
|
||||
|
||||
fn fetch_metadata(url: Url, version: MetadataVersion) -> Result<Metadata, CodegenError> {
|
||||
let bytes = fetch_metadata_bytes_blocking(url, version)?;
|
||||
Ok(Metadata::decode(&mut &bytes[..])?)
|
||||
@@ -225,49 +228,10 @@ impl RuntimeGenerator {
|
||||
///
|
||||
/// Supported versions: v14 and v15.
|
||||
pub fn new(mut metadata: Metadata) -> Self {
|
||||
Self::ensure_unique_type_paths(&mut metadata);
|
||||
metadata.ensure_unique_type_paths();
|
||||
RuntimeGenerator { metadata }
|
||||
}
|
||||
|
||||
/// Ensure that every unique type we'll be generating or referring to also has a
|
||||
/// unique path, so that types with matching paths don't end up overwriting each other
|
||||
/// in the codegen. We ignore any types with generics; Subxt actually endeavours to
|
||||
/// de-duplicate those into single types with a generic.
|
||||
fn ensure_unique_type_paths(metadata: &mut Metadata) {
|
||||
let mut visited_path_counts = HashMap::<Vec<String>, usize>::new();
|
||||
for ty in metadata.types_mut().types.iter_mut() {
|
||||
// Ignore types without a path (ie prelude types).
|
||||
if ty.ty.path.namespace().is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let has_valid_type_params = ty.ty.type_params.iter().any(|tp| tp.ty.is_some());
|
||||
|
||||
// Ignore types which have generic params that the type generation will use.
|
||||
// Ordinarily we'd expect that any two types with identical paths must be parameterized
|
||||
// in order to share the path. However scale-info doesn't understand all forms of generics
|
||||
// properly I think (eg generics that have associated types that can differ), and so in
|
||||
// those cases we need to fix the paths for Subxt to generate correct code.
|
||||
if has_valid_type_params {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Count how many times we've seen the same path already.
|
||||
let visited_count = visited_path_counts
|
||||
.entry(ty.ty.path.segments.clone())
|
||||
.or_default();
|
||||
*visited_count += 1;
|
||||
|
||||
// alter the type so that if it's been seen more than once, we append a number to
|
||||
// its name to ensure that every unique type has a unique path, too.
|
||||
if *visited_count > 1 {
|
||||
if let Some(name) = ty.ty.path.segments.last_mut() {
|
||||
*name = format!("{name}{visited_count}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate the API for interacting with a Substrate runtime.
|
||||
///
|
||||
/// # Arguments
|
||||
|
||||
@@ -96,10 +96,7 @@ fn generate_storage_entry_fns(
|
||||
};
|
||||
|
||||
let snake_case_name = storage_entry.name().to_snake_case();
|
||||
let storage_entry_ty = match storage_entry.entry_type() {
|
||||
StorageEntryType::Plain(ty) => *ty,
|
||||
StorageEntryType::Map { value_ty, .. } => *value_ty,
|
||||
};
|
||||
let storage_entry_ty = storage_entry.entry_type().value_ty();
|
||||
let storage_entry_value_ty = type_gen.resolve_type_path(storage_entry_ty);
|
||||
let docs = storage_entry.docs();
|
||||
let docs = should_gen_docs
|
||||
|
||||
@@ -8,6 +8,7 @@ use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||
|
||||
/// Error returned when the Codegen cannot generate the runtime API.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum CodegenError {
|
||||
/// The given metadata type could not be found.
|
||||
#[error("Could not find type with ID {0} in the type registry; please raise a support issue.")]
|
||||
@@ -82,11 +83,13 @@ impl CodegenError {
|
||||
|
||||
/// Error attempting to load metadata.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum FetchMetadataError {
|
||||
#[error("Cannot decode hex value: {0}")]
|
||||
DecodeError(#[from] hex::FromHexError),
|
||||
#[error("Cannot scale encode/decode value: {0}")]
|
||||
CodecError(#[from] codec::Error),
|
||||
#[cfg(feature = "fetch-metadata")]
|
||||
#[error("Request error: {0}")]
|
||||
RequestError(#[from] jsonrpsee::core::Error),
|
||||
#[error("'{0}' not supported, supported URI schemes are http, https, ws or wss.")]
|
||||
@@ -97,6 +100,7 @@ pub enum FetchMetadataError {
|
||||
|
||||
/// Error attempting to do type substitution.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum TypeSubstitutionError {
|
||||
/// Substitute "to" type must be an absolute path.
|
||||
#[error("`substitute_type(with = <path>)` must be a path prefixed with 'crate::' or '::'")]
|
||||
|
||||
+8
-1
@@ -50,10 +50,17 @@ mod error;
|
||||
mod ir;
|
||||
mod types;
|
||||
|
||||
#[cfg(feature = "fetch-metadata")]
|
||||
pub mod utils;
|
||||
|
||||
#[cfg(all(feature = "web", feature = "fetch-metadata"))]
|
||||
compile_error!("subxt-codegen: the features 'web' and 'fetch_metadata' cannot be used together.");
|
||||
|
||||
pub use self::{
|
||||
api::{GenerateRuntimeApi, RuntimeGenerator},
|
||||
error::{CodegenError, TypeSubstitutionError},
|
||||
types::{CratePath, Derives, DerivesRegistry, Module, TypeGenerator, TypeSubstitutes},
|
||||
types::{
|
||||
CratePath, Derives, DerivesRegistry, Module, TypeDefGen, TypeDefParameters, TypeGenerator,
|
||||
TypeSubstitutes,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -262,6 +262,11 @@ impl<'a> TypeGenerator<'a> {
|
||||
self.derives.default_derives()
|
||||
}
|
||||
|
||||
/// Returns the type registry.
|
||||
pub fn types(&self) -> &PortableRegistry {
|
||||
self.type_registry
|
||||
}
|
||||
|
||||
/// Returns the derives to be applied to a generated type.
|
||||
pub fn type_derives(&self, ty: &Type<PortableForm>) -> Result<Derives, CodegenError> {
|
||||
let joined_path = ty.path.segments.join("::");
|
||||
|
||||
@@ -118,6 +118,11 @@ impl TypeDefGen {
|
||||
ty_docs,
|
||||
})
|
||||
}
|
||||
|
||||
/// are there unused type params?
|
||||
pub fn has_unused_type_params(&self) -> bool {
|
||||
self.type_params.has_unused_type_params()
|
||||
}
|
||||
}
|
||||
|
||||
impl quote::ToTokens for TypeDefGen {
|
||||
|
||||
@@ -60,6 +60,11 @@ impl TypeDefParameters {
|
||||
pub fn params(&self) -> &[TypeParameter] {
|
||||
&self.params
|
||||
}
|
||||
|
||||
/// Returns true if there are any unused type params
|
||||
pub fn has_unused_type_params(&self) -> bool {
|
||||
!self.unused.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl quote::ToTokens for TypeDefParameters {
|
||||
|
||||
Reference in New Issue
Block a user