Files
pezkuwi-subxt/macro/src/lib.rs
Tadeo Hepperle fc5a18aaa0 Use scale-typegen as a backend for the codegen (#1260)
* integrate scale-typegen, remove types mod

* reintroduce default substitutes and derives

* support runtime_types only again

* generating polkadot.rs ok

* update scale-typegen to discrete error types

* scale-typegen-api-changes

* add note about UncheckedExtrinsic in default substitutes

* add resursive attributes and derives

* adjust example where Clone bound recursive

* move scale-typegen dependency to workspace

* expose default typegen settings

* lightclient: Fix wasm socket closure called after being dropped (#1289)

* lightclient: Close wasm socket while dropping from connecting state

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Construct one time only closures

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* testing: Enable console logs for lightclient WASM testing

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Separate wakes and check connectivity on poll_read

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Close the socket depending on internal state

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Revert "lightclient: Separate wakes and check connectivity on poll_read"

This reverts commit 866094001d4c0b119a80ed681a74b323f74eae1b.

* lightclient: Return pending if socket is opening from poll_read

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Close the socket on `poll_close`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Reset closures on Drop to avoid recursive invokation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Close the socket if not already closing

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* workflows: Install rustup component for building substrate (#1295)

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Command to fetch chainSpec and optimise its size (#1278)

* cli: Add chainSpec command

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli/chainSpec: Move to dedicated module

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Compute the state root hash

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Remove code substitutes

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* artifacts: Update polkadot.json

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* scripts: Generate the chain spec

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Remove testing artifacts

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Fix clippy

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Apply rustfmt

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Introduce feature flag for smoldot dependency

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Rename chain-spec to chain-spec-pruning

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* scripts: Update chain-spec command

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* remove comments and unused args

* Update substrate- and signer-related dependencies (#1297)

* update crypto dependencies, adjust keypair

* add scale_info::TypeInfo derive in some places

* add multi signature derive

* fix lock file

* fix lock file again :|

* adjust to new interface in scale-typegen

* use released scale typegen

* reintroduce type aliases

* introduce type aliases again using scale-typegen

* cargo fmt and clippy

* reconcile changes with master branch

* update polkadot.rs

* bump scale-typgen to fix substitution

* implemented Alex suggestions, regenerated polkadot.rs (did not change)

* resolve conflicts in Cargo.lock

* make expect messages more clear

* correct typos

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
2024-01-11 16:42:51 +01:00

205 lines
6.5 KiB
Rust

// 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.
//! Subxt macro for generating Substrate runtime interfaces.
extern crate proc_macro;
use codec::Decode;
use darling::{ast::NestedMeta, FromMeta};
use proc_macro::TokenStream;
use proc_macro_error::{abort_call_site, proc_macro_error};
use subxt_codegen::{
fetch_metadata::{
fetch_metadata_from_file_blocking, fetch_metadata_from_url_blocking, MetadataVersion, Url,
},
CodegenBuilder, CodegenError,
};
use syn::{parse_macro_input, punctuated::Punctuated};
#[derive(Clone, Debug)]
struct OuterAttribute(syn::Attribute);
impl syn::parse::Parse for OuterAttribute {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Ok(Self(input.call(syn::Attribute::parse_outer)?[0].clone()))
}
}
#[derive(Debug, FromMeta)]
struct RuntimeMetadataArgs {
#[darling(default)]
runtime_metadata_path: Option<String>,
#[darling(default)]
runtime_metadata_insecure_url: Option<String>,
#[darling(default)]
derive_for_all_types: Option<Punctuated<syn::Path, syn::Token![,]>>,
#[darling(default)]
attributes_for_all_types: Option<Punctuated<OuterAttribute, syn::Token![,]>>,
#[darling(multiple)]
derive_for_type: Vec<DeriveForType>,
#[darling(multiple)]
attributes_for_type: Vec<AttributesForType>,
#[darling(multiple)]
substitute_type: Vec<SubstituteType>,
#[darling(default, rename = "crate")]
crate_path: Option<syn::Path>,
#[darling(default)]
generate_docs: darling::util::Flag,
#[darling(default)]
runtime_types_only: bool,
#[darling(default)]
no_default_derives: bool,
#[darling(default)]
no_default_substitutions: bool,
#[darling(default)]
unstable_metadata: darling::util::Flag,
}
#[derive(Debug, FromMeta)]
struct DeriveForType {
path: syn::TypePath,
derive: Punctuated<syn::Path, syn::Token![,]>,
#[darling(default)]
recursive: bool,
}
#[derive(Debug, FromMeta)]
struct AttributesForType {
path: syn::TypePath,
attributes: Punctuated<OuterAttribute, syn::Token![,]>,
#[darling(default)]
recursive: bool,
}
#[derive(Debug, FromMeta)]
struct SubstituteType {
path: syn::Path,
with: syn::Path,
}
// Note: docs for this are in the subxt library; don't add further docs here as they will be appended.
#[proc_macro_attribute]
#[proc_macro_error]
pub fn subxt(args: TokenStream, input: TokenStream) -> TokenStream {
let attr_args = match NestedMeta::parse_meta_list(args.into()) {
Ok(v) => v,
Err(e) => {
return TokenStream::from(darling::Error::from(e).write_errors());
}
};
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 mut codegen = CodegenBuilder::new();
// Use the item module that the macro is on:
codegen.set_target_module(item_mod);
// Use the provided crate path:
if let Some(crate_path) = args.crate_path {
codegen.set_subxt_crate_path(crate_path)
}
// Respect the boolean flags:
if args.runtime_types_only {
codegen.runtime_types_only();
}
if args.no_default_derives {
codegen.disable_default_derives();
}
if args.no_default_substitutions {
codegen.disable_default_substitutes();
}
if !args.generate_docs.is_present() {
codegen.no_docs()
}
// Configure derives:
codegen.set_additional_global_derives(
args.derive_for_all_types
.unwrap_or_default()
.into_iter()
.collect(),
);
for d in args.derive_for_type {
codegen.add_derives_for_type(d.path, d.derive.into_iter(), d.recursive);
}
// Configure attributes:
codegen.set_additional_global_attributes(
args.attributes_for_all_types
.unwrap_or_default()
.into_iter()
.map(|a| a.0)
.collect(),
);
for d in args.attributes_for_type {
codegen.add_attributes_for_type(d.path, d.attributes.into_iter().map(|a| a.0), d.recursive)
}
// Insert type substitutions:
for sub in args.substitute_type.into_iter() {
codegen.set_type_substitute(sub.path, sub.with);
}
// Do we want to fetch unstable metadata? This only works if fetching from a URL.
let unstable_metadata = args.unstable_metadata.is_present();
match (
args.runtime_metadata_path,
args.runtime_metadata_insecure_url,
) {
(Some(rest_of_path), None) => {
if unstable_metadata {
abort_call_site!(
"The 'unstable_metadata' attribute requires `runtime_metadata_insecure_url`"
)
}
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(rest_of_path);
let generated_code = fetch_metadata_from_file_blocking(&path)
.map_err(CodegenError::from)
.and_then(|b| subxt_codegen::Metadata::decode(&mut &*b).map_err(Into::into))
.and_then(|m| codegen.generate(m).map_err(Into::into))
.unwrap_or_else(|e| e.into_compile_error());
generated_code.into()
}
(None, Some(url_string)) => {
let url = Url::parse(&url_string).unwrap_or_else(|_| {
abort_call_site!("Cannot download metadata; invalid url: {}", url_string)
});
let version = match unstable_metadata {
true => MetadataVersion::Unstable,
false => MetadataVersion::Latest,
};
let generated_code = fetch_metadata_from_url_blocking(url, version)
.map_err(CodegenError::from)
.and_then(|b| subxt_codegen::Metadata::decode(&mut &*b).map_err(Into::into))
.and_then(|m| codegen.generate(m).map_err(Into::into))
.unwrap_or_else(|e| e.into_compile_error());
generated_code.into()
}
(None, None) => {
abort_call_site!(
"One of 'runtime_metadata_path' or 'runtime_metadata_insecure_url' must be provided"
)
}
(Some(_), Some(_)) => {
abort_call_site!(
"Only one of 'runtime_metadata_path' or 'runtime_metadata_insecure_url' can be provided"
)
}
}
}