mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 06:27:58 +00:00
f115ff975c
* Allow specifying the `subxt` crate path for generated code * Make `clippy` happy * Add documentation * Improve optics * Remove custom crate path test * Implement comments * Update comment * Make `crate_path` property instead of argument * Remove unnecessary derives * Remove `Default` impls in favor of explicit constructors * Remove unnecessary `into` * Update codegen/src/types/mod.rs Co-authored-by: Andrew Jones <ascjones@gmail.com> Co-authored-by: Andrew Jones <ascjones@gmail.com>
152 lines
4.7 KiB
Rust
152 lines
4.7 KiB
Rust
// 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.
|
|
|
|
//! Generate a strongly typed API for interacting with a Substrate runtime from its metadata.
|
|
//!
|
|
//! Usage:
|
|
//!
|
|
//! Download metadata from a running Substrate node using `subxt-cli`:
|
|
//!
|
|
//! ```bash
|
|
//! subxt metadata > polkadot_metadata.scale
|
|
//! ```
|
|
//!
|
|
//! Annotate a Rust module with the `subxt` attribute referencing the aforementioned metadata file.
|
|
//!
|
|
//! ```ignore
|
|
//! #[subxt::subxt(
|
|
//! runtime_metadata_path = "polkadot_metadata.scale",
|
|
//! )]
|
|
//! pub mod polkadot {}
|
|
//! ```
|
|
//!
|
|
//! The `subxt` macro will populate the annotated module with all of the methods and types required
|
|
//! for submitting extrinsics and reading from storage for the given runtime.
|
|
//!
|
|
//! ## Substituting types
|
|
//!
|
|
//! In order to replace a generated type by a user-defined type, use `substitute_type`:
|
|
//!
|
|
//! ```ignore
|
|
//! #[subxt::subxt(
|
|
//! runtime_metadata_path = "polkadot_metadata.scale",
|
|
//! )]
|
|
//! pub mod polkadot {
|
|
//! #[subxt(substitute_type = "sp_arithmetic::per_things::Perbill")]
|
|
//! use sp_runtime::Perbill;
|
|
//! }
|
|
//! ```
|
|
//!
|
|
//! This will replace the generated type and any usages with the specified type at the `use` import.
|
|
//! It is useful for using custom decoding for specific types, or to provide a type with foreign
|
|
//! trait implementations, or other specialized functionality.
|
|
|
|
//! ## Custom Derives
|
|
//!
|
|
//! By default all generated types are annotated with `scale::Encode` and `scale::Decode` derives.
|
|
//! However when using the generated types in the client, they may require additional derives to be
|
|
//! useful.
|
|
//!
|
|
//! ### Adding derives for all types
|
|
//!
|
|
//! Add `derive_for_all_types` with a comma seperated list of the derives to apply to *all* types
|
|
//!
|
|
//! ```ignore
|
|
//! #[subxt::subxt(
|
|
//! runtime_metadata_path = "polkadot_metadata.scale",
|
|
//! derive_for_all_types = "Eq, PartialEq"
|
|
//! )]
|
|
//! pub mod polkadot {}
|
|
//! ```
|
|
//!
|
|
//! ### Adding derives for specific types
|
|
//!
|
|
//! Add `derive_for_type` for each specific type with a comma seperated list of the derives to
|
|
//! apply for that type only.
|
|
//!
|
|
//! ```ignore
|
|
//! #[subxt::subxt(
|
|
//! runtime_metadata_path = "polkadot_metadata.scale",
|
|
//! derive_for_all_types = "Eq, PartialEq",
|
|
//! derive_for_type(type = "frame_support::PalletId", derive = "Ord, PartialOrd"),
|
|
//! derive_for_type(type = "sp_runtime::ModuleError", derive = "Hash"),
|
|
//! )]
|
|
//! pub mod polkadot {}
|
|
//! ```
|
|
//!
|
|
//! ### Custom crate path
|
|
//!
|
|
//! In order to specify a custom crate path to be used for the code generation:
|
|
//!
|
|
//! ```ignore
|
|
//! #[subxt::subxt(crate = "crate::path::to::subxt")]
|
|
//! ```
|
|
//!
|
|
//! By default the path `::subxt` is used.
|
|
|
|
#![deny(unused_crate_dependencies)]
|
|
|
|
extern crate proc_macro;
|
|
|
|
use darling::FromMeta;
|
|
use proc_macro::TokenStream;
|
|
use proc_macro_error::proc_macro_error;
|
|
use subxt_codegen::DerivesRegistry;
|
|
use syn::{
|
|
parse_macro_input,
|
|
punctuated::Punctuated,
|
|
};
|
|
|
|
#[derive(Debug, FromMeta)]
|
|
struct RuntimeMetadataArgs {
|
|
runtime_metadata_path: String,
|
|
#[darling(default)]
|
|
derive_for_all_types: Option<Punctuated<syn::Path, syn::Token![,]>>,
|
|
#[darling(multiple)]
|
|
derive_for_type: Vec<DeriveForType>,
|
|
#[darling(default, rename = "crate")]
|
|
crate_path: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, FromMeta)]
|
|
struct DeriveForType {
|
|
#[darling(rename = "type")]
|
|
ty: syn::TypePath,
|
|
derive: Punctuated<syn::Path, syn::Token![,]>,
|
|
}
|
|
|
|
#[proc_macro_attribute]
|
|
#[proc_macro_error]
|
|
pub fn subxt(args: TokenStream, input: TokenStream) -> TokenStream {
|
|
let attr_args = parse_macro_input!(args as syn::AttributeArgs);
|
|
let item_mod = parse_macro_input!(input as syn::ItemMod);
|
|
let args = match RuntimeMetadataArgs::from_list(&attr_args) {
|
|
Ok(v) => v,
|
|
Err(e) => return TokenStream::from(e.write_errors()),
|
|
};
|
|
|
|
let root = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into());
|
|
let root_path = std::path::Path::new(&root);
|
|
let path = root_path.join(args.runtime_metadata_path);
|
|
|
|
let crate_path = match args.crate_path {
|
|
Some(crate_path) => crate_path.into(),
|
|
None => subxt_codegen::CratePath::default(),
|
|
};
|
|
let mut derives_registry = DerivesRegistry::new(&crate_path);
|
|
if let Some(derive_for_all) = args.derive_for_all_types {
|
|
derives_registry.extend_for_all(derive_for_all.iter().cloned());
|
|
}
|
|
for derives in &args.derive_for_type {
|
|
derives_registry.extend_for_type(
|
|
derives.ty.clone(),
|
|
derives.derive.iter().cloned(),
|
|
&crate_path,
|
|
)
|
|
}
|
|
|
|
subxt_codegen::generate_runtime_api(item_mod, &path, derives_registry, crate_path)
|
|
.into()
|
|
}
|