mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 21:11:07 +00:00
Generate only runtime types (#845)
* Typos * Add new macro parameter. Refactor. * Code generation * Inline `runtime_types` module * Documentation * Can't inline so easily * Example * Remove leftover * Improve clarity of the example
This commit is contained in:
committed by
GitHub
parent
29a4a48dcc
commit
c9527abaa8
@@ -45,6 +45,9 @@ pub struct Opts {
|
||||
/// Defaults to `false` (documentation is generated).
|
||||
#[clap(long, action)]
|
||||
no_docs: bool,
|
||||
/// Whether to limit code generation to only runtime types.
|
||||
#[clap(long)]
|
||||
runtime_types_only: bool,
|
||||
}
|
||||
|
||||
fn derive_for_type_parser(src: &str) -> Result<(String, String), String> {
|
||||
@@ -80,6 +83,7 @@ pub async fn run(opts: Opts) -> color_eyre::Result<()> {
|
||||
opts.derives_for_type,
|
||||
opts.crate_path,
|
||||
opts.no_docs,
|
||||
opts.runtime_types_only,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -90,6 +94,7 @@ fn codegen(
|
||||
derives_for_type: Vec<(String, String)>,
|
||||
crate_path: Option<String>,
|
||||
no_docs: bool,
|
||||
runtime_types_only: bool,
|
||||
) -> color_eyre::Result<()> {
|
||||
let item_mod = syn::parse_quote!(
|
||||
pub mod api {}
|
||||
@@ -120,6 +125,7 @@ fn codegen(
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
runtime_types_only,
|
||||
);
|
||||
match runtime_api {
|
||||
Ok(runtime_api) => println!("{runtime_api}"),
|
||||
|
||||
+76
-7
@@ -121,6 +121,7 @@ impl CodegenError {
|
||||
/// * `type_substitutes` - Provide custom type substitutes.
|
||||
/// * `crate_path` - Path to the `subxt` crate.
|
||||
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
|
||||
/// * `runtime_types_only` - Whether to limit code generation to only runtime types.
|
||||
///
|
||||
/// **Note:** This is a wrapper over [RuntimeGenerator] for static metadata use-cases.
|
||||
pub fn generate_runtime_api_from_path<P>(
|
||||
@@ -130,6 +131,7 @@ pub fn generate_runtime_api_from_path<P>(
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
should_gen_docs: bool,
|
||||
runtime_types_only: bool,
|
||||
) -> Result<TokenStream2, CodegenError>
|
||||
where
|
||||
P: AsRef<path::Path>,
|
||||
@@ -147,6 +149,7 @@ where
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
runtime_types_only,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -162,6 +165,7 @@ where
|
||||
/// * `type_substitutes` - Provide custom type substitutes.
|
||||
/// * `crate_path` - Path to the `subxt` crate.
|
||||
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
|
||||
/// * `runtime_types_only` - Whether to limit code generation to only runtime types.
|
||||
///
|
||||
/// **Note:** This is a wrapper over [RuntimeGenerator] for static metadata use-cases.
|
||||
pub fn generate_runtime_api_from_url(
|
||||
@@ -171,6 +175,7 @@ pub fn generate_runtime_api_from_url(
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
should_gen_docs: bool,
|
||||
runtime_types_only: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let bytes = fetch_metadata_bytes_blocking(url)?;
|
||||
|
||||
@@ -181,6 +186,7 @@ pub fn generate_runtime_api_from_url(
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
runtime_types_only,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -194,6 +200,7 @@ pub fn generate_runtime_api_from_url(
|
||||
/// * `type_substitutes` - Provide custom type substitutes.
|
||||
/// * `crate_path` - Path to the `subxt` crate.
|
||||
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
|
||||
/// * `runtime_types_only` - Whether to limit code generation to only runtime types.
|
||||
///
|
||||
/// **Note:** This is a wrapper over [RuntimeGenerator] for static metadata use-cases.
|
||||
pub fn generate_runtime_api_from_bytes(
|
||||
@@ -203,17 +210,28 @@ pub fn generate_runtime_api_from_bytes(
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
should_gen_docs: bool,
|
||||
runtime_types_only: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let metadata = frame_metadata::RuntimeMetadataPrefixed::decode(&mut &bytes[..])?;
|
||||
|
||||
let generator = RuntimeGenerator::new(metadata);
|
||||
generator.generate_runtime(
|
||||
item_mod,
|
||||
derives,
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
)
|
||||
if runtime_types_only {
|
||||
generator.generate_runtime_types(
|
||||
item_mod,
|
||||
derives,
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
)
|
||||
} else {
|
||||
generator.generate_runtime(
|
||||
item_mod,
|
||||
derives,
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the API for interacting with a Substrate runtime.
|
||||
@@ -240,6 +258,57 @@ impl RuntimeGenerator {
|
||||
///
|
||||
/// * `item_mod` - The module declaration for which the API is implemented.
|
||||
/// * `derives` - Provide custom derives for the generated types.
|
||||
/// * `type_substitutes` - Provide custom type substitutes.
|
||||
/// * `crate_path` - Path to the `subxt` crate.
|
||||
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
|
||||
pub fn generate_runtime_types(
|
||||
&self,
|
||||
item_mod: syn::ItemMod,
|
||||
derives: DerivesRegistry,
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let item_mod_attrs = item_mod.attrs.clone();
|
||||
|
||||
let item_mod_ir = ir::ItemMod::try_from(item_mod)?;
|
||||
let mod_ident = &item_mod_ir.ident;
|
||||
let rust_items = item_mod_ir.rust_items();
|
||||
|
||||
let type_gen = TypeGenerator::new(
|
||||
&self.metadata.types,
|
||||
"runtime_types",
|
||||
type_substitutes,
|
||||
derives,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
);
|
||||
let types_mod = type_gen.generate_types_mod()?;
|
||||
|
||||
Ok(quote! {
|
||||
#( #item_mod_attrs )*
|
||||
#[allow(dead_code, unused_imports, non_camel_case_types)]
|
||||
#[allow(clippy::all)]
|
||||
pub mod #mod_ident {
|
||||
// Preserve any Rust items that were previously defined in the adorned module
|
||||
#( #rust_items ) *
|
||||
|
||||
// Make it easy to access the root via `root_mod` at different levels:
|
||||
use super::#mod_ident as root_mod;
|
||||
#types_mod
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the API for interacting with a Substrate runtime.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `item_mod` - The module declaration for which the API is implemented.
|
||||
/// * `derives` - Provide custom derives for the generated types.
|
||||
/// * `type_substitutes` - Provide custom type substitutes.
|
||||
/// * `crate_path` - Path to the `subxt` crate.
|
||||
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
|
||||
pub fn generate_runtime(
|
||||
&self,
|
||||
item_mod: syn::ItemMod,
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! In some cases we are interested only in the `RuntimeCall` enum (or more generally, only in some
|
||||
//! runtime types). We can ask `subxt` to generate only runtime types by passing a corresponding
|
||||
//! flag.
|
||||
//!
|
||||
//! Here we present how to correctly create `Block` type for the Polkadot chain.
|
||||
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
generic,
|
||||
traits::{
|
||||
BlakeTwo256,
|
||||
Block as _,
|
||||
Header as _,
|
||||
},
|
||||
Digest,
|
||||
};
|
||||
use subxt::PolkadotConfig;
|
||||
|
||||
#[subxt::subxt(
|
||||
runtime_metadata_path = "../artifacts/polkadot_metadata.scale",
|
||||
derive_for_all_types = "Clone, PartialEq, Eq",
|
||||
runtime_types_only
|
||||
)]
|
||||
pub mod polkadot {}
|
||||
|
||||
type RuntimeCall = polkadot::runtime_types::polkadot_runtime::RuntimeCall;
|
||||
|
||||
type UncheckedExtrinsic = generic::UncheckedExtrinsic<
|
||||
<PolkadotConfig as subxt::Config>::Address,
|
||||
RuntimeCall,
|
||||
<PolkadotConfig as subxt::Config>::Signature,
|
||||
// Usually we are not interested in `SignedExtra`.
|
||||
(),
|
||||
>;
|
||||
|
||||
type Header = generic::Header<u32, BlakeTwo256>;
|
||||
type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Although we could build an online client, we do not have access to the full runtime API. For
|
||||
// that, we would have to specify `runtime_types_only = false` (or just skipping it).
|
||||
//
|
||||
// let api = subxt::OnlineClient::<PolkadotConfig>::new().await?;
|
||||
// let address = polkadot::constants().balances().existential_deposit(); <- this won't compile!
|
||||
|
||||
let polkadot_header = Header::new(
|
||||
41,
|
||||
H256::default(),
|
||||
H256::default(),
|
||||
H256::default(),
|
||||
Digest::default(),
|
||||
);
|
||||
|
||||
let polkadot_block = Block::new(polkadot_header, vec![]);
|
||||
|
||||
println!("{polkadot_block:?}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+17
-2
@@ -48,7 +48,7 @@
|
||||
//!
|
||||
//! ### Adding derives for all types
|
||||
//!
|
||||
//! Add `derive_for_all_types` with a comma seperated list of the derives to apply to *all* types
|
||||
//! Add `derive_for_all_types` with a comma separated list of the derives to apply to *all* types
|
||||
//!
|
||||
//! ```ignore
|
||||
//! #[subxt::subxt(
|
||||
@@ -60,7 +60,7 @@
|
||||
//!
|
||||
//! ### Adding derives for specific types
|
||||
//!
|
||||
//! Add `derive_for_type` for each specific type with a comma seperated list of the derives to
|
||||
//! Add `derive_for_type` for each specific type with a comma separated list of the derives to
|
||||
//! apply for that type only.
|
||||
//!
|
||||
//! ```ignore
|
||||
@@ -95,6 +95,17 @@
|
||||
//! ```
|
||||
//!
|
||||
//! By default the documentation is not generated.
|
||||
//!
|
||||
//! ### Runtime types generation
|
||||
//!
|
||||
//! In some cases, you may be interested only in the runtime types, like `RuntimeCall` enum. You can
|
||||
//! limit code generation to just `runtime_types` module with `runtime_types_only` flag:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! #[subxt::subxt(runtime_types_only)]
|
||||
//! // or equivalently
|
||||
//! #[subxt::subxt(runtime_types_only = true)]
|
||||
//! ```
|
||||
|
||||
#![deny(unused_crate_dependencies)]
|
||||
|
||||
@@ -136,6 +147,8 @@ struct RuntimeMetadataArgs {
|
||||
crate_path: Option<String>,
|
||||
#[darling(default)]
|
||||
generate_docs: darling::util::Flag,
|
||||
#[darling(default)]
|
||||
runtime_types_only: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromMeta)]
|
||||
@@ -207,6 +220,7 @@ pub fn subxt(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
args.runtime_types_only,
|
||||
)
|
||||
.map_or_else(|err| err.into_compile_error().into(), Into::into)
|
||||
}
|
||||
@@ -221,6 +235,7 @@ pub fn subxt(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
args.runtime_types_only,
|
||||
)
|
||||
.map_or_else(|err| err.into_compile_error().into(), Into::into)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user