mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-23 01:28:00 +00:00
Allow specifying the subxt crate path for generated code (#664)
* 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>
This commit is contained in:
@@ -2,9 +2,12 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::types::{
|
||||
CompositeDefFields,
|
||||
TypeGenerator,
|
||||
use crate::{
|
||||
types::{
|
||||
CompositeDefFields,
|
||||
TypeGenerator,
|
||||
},
|
||||
CratePath,
|
||||
};
|
||||
use frame_metadata::{
|
||||
v14::RuntimeMetadataV14,
|
||||
@@ -36,6 +39,7 @@ pub fn generate_calls(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata<PortableForm>,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
) -> TokenStream2 {
|
||||
// Early return if the pallet has no calls.
|
||||
let call = if let Some(ref calls) = pallet.calls {
|
||||
@@ -49,6 +53,7 @@ pub fn generate_calls(
|
||||
call.ty.id(),
|
||||
|name| name.to_upper_camel_case().into(),
|
||||
"Call",
|
||||
crate_path,
|
||||
);
|
||||
let (call_structs, call_fns): (Vec<_>, Vec<_>) = struct_defs
|
||||
.iter_mut()
|
||||
@@ -98,13 +103,14 @@ pub fn generate_calls(
|
||||
let call_struct = quote! {
|
||||
#struct_def
|
||||
};
|
||||
|
||||
let client_fn = quote! {
|
||||
#docs
|
||||
pub fn #fn_name(
|
||||
&self,
|
||||
#( #call_fn_args, )*
|
||||
) -> ::subxt::tx::StaticTxPayload<#struct_name> {
|
||||
::subxt::tx::StaticTxPayload::new(
|
||||
) -> #crate_path::tx::StaticTxPayload<#struct_name> {
|
||||
#crate_path::tx::StaticTxPayload::new(
|
||||
#pallet_name,
|
||||
#call_name,
|
||||
#struct_name { #( #call_args, )* },
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::types::TypeGenerator;
|
||||
use crate::{
|
||||
types::TypeGenerator,
|
||||
CratePath,
|
||||
};
|
||||
use frame_metadata::{
|
||||
v14::RuntimeMetadataV14,
|
||||
PalletMetadata,
|
||||
@@ -44,6 +47,7 @@ pub fn generate_constants(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata<PortableForm>,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
) -> TokenStream2 {
|
||||
// Early return if the pallet has no constants.
|
||||
if pallet.constants.is_empty() {
|
||||
@@ -63,8 +67,8 @@ pub fn generate_constants(
|
||||
|
||||
quote! {
|
||||
#( #[doc = #docs ] )*
|
||||
pub fn #fn_name(&self) -> ::subxt::constants::StaticConstantAddress<::subxt::metadata::DecodeStaticType<#return_ty>> {
|
||||
::subxt::constants::StaticConstantAddress::new(
|
||||
pub fn #fn_name(&self) -> #crate_path::constants::StaticConstantAddress<#crate_path::metadata::DecodeStaticType<#return_ty>> {
|
||||
#crate_path::constants::StaticConstantAddress::new(
|
||||
#pallet_name,
|
||||
#constant_name,
|
||||
[#(#constant_hash,)*]
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::types::TypeGenerator;
|
||||
use crate::{
|
||||
types::TypeGenerator,
|
||||
CratePath,
|
||||
};
|
||||
use frame_metadata::PalletMetadata;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
@@ -41,6 +44,7 @@ pub fn generate_events(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata<PortableForm>,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
) -> TokenStream2 {
|
||||
// Early return if the pallet has no events.
|
||||
let event = if let Some(ref event) = pallet.event {
|
||||
@@ -54,6 +58,7 @@ pub fn generate_events(
|
||||
event.ty.id(),
|
||||
|name| name.into(),
|
||||
"Event",
|
||||
crate_path,
|
||||
);
|
||||
let event_structs = struct_defs.iter().map(|(variant_name, struct_def)| {
|
||||
let pallet_name = &pallet.name;
|
||||
@@ -63,7 +68,7 @@ pub fn generate_events(
|
||||
quote! {
|
||||
#struct_def
|
||||
|
||||
impl ::subxt::events::StaticEvent for #event_struct {
|
||||
impl #crate_path::events::StaticEvent for #event_struct {
|
||||
const PALLET: &'static str = #pallet_name;
|
||||
const EVENT: &'static str = #event_name;
|
||||
}
|
||||
|
||||
+27
-13
@@ -19,6 +19,7 @@ use crate::{
|
||||
CompositeDefFields,
|
||||
TypeGenerator,
|
||||
},
|
||||
CratePath,
|
||||
};
|
||||
use codec::Decode;
|
||||
use frame_metadata::{
|
||||
@@ -55,6 +56,7 @@ pub fn generate_runtime_api<P>(
|
||||
item_mod: syn::ItemMod,
|
||||
path: P,
|
||||
derives: DerivesRegistry,
|
||||
crate_path: CratePath,
|
||||
) -> TokenStream2
|
||||
where
|
||||
P: AsRef<path::Path>,
|
||||
@@ -71,7 +73,7 @@ where
|
||||
.unwrap_or_else(|e| abort_call_site!("Failed to decode metadata: {}", e));
|
||||
|
||||
let generator = RuntimeGenerator::new(metadata);
|
||||
generator.generate_runtime(item_mod, derives)
|
||||
generator.generate_runtime(item_mod, derives, crate_path)
|
||||
}
|
||||
|
||||
/// Create the API for interacting with a Substrate runtime.
|
||||
@@ -101,6 +103,7 @@ impl RuntimeGenerator {
|
||||
&self,
|
||||
item_mod: syn::ItemMod,
|
||||
derives: DerivesRegistry,
|
||||
crate_path: CratePath,
|
||||
) -> TokenStream2 {
|
||||
let item_mod_ir = ir::ItemMod::from(item_mod);
|
||||
let default_derives = derives.default_derives();
|
||||
@@ -109,41 +112,41 @@ impl RuntimeGenerator {
|
||||
let mut type_substitutes = [
|
||||
(
|
||||
"bitvec::order::Lsb0",
|
||||
parse_quote!(::subxt::ext::bitvec::order::Lsb0),
|
||||
parse_quote!(#crate_path::ext::bitvec::order::Lsb0),
|
||||
),
|
||||
(
|
||||
"bitvec::order::Msb0",
|
||||
parse_quote!(::subxt::ext::bitvec::order::Msb0),
|
||||
parse_quote!(#crate_path::ext::bitvec::order::Msb0),
|
||||
),
|
||||
(
|
||||
"sp_core::crypto::AccountId32",
|
||||
parse_quote!(::subxt::ext::sp_core::crypto::AccountId32),
|
||||
parse_quote!(#crate_path::ext::sp_core::crypto::AccountId32),
|
||||
),
|
||||
(
|
||||
"primitive_types::H160",
|
||||
parse_quote!(::subxt::ext::sp_core::H160),
|
||||
parse_quote!(#crate_path::ext::sp_core::H160),
|
||||
),
|
||||
(
|
||||
"primitive_types::H256",
|
||||
parse_quote!(::subxt::ext::sp_core::H256),
|
||||
parse_quote!(#crate_path::ext::sp_core::H256),
|
||||
),
|
||||
(
|
||||
"primitive_types::H512",
|
||||
parse_quote!(::subxt::ext::sp_core::H512),
|
||||
parse_quote!(#crate_path::ext::sp_core::H512),
|
||||
),
|
||||
(
|
||||
"sp_runtime::multiaddress::MultiAddress",
|
||||
parse_quote!(::subxt::ext::sp_runtime::MultiAddress),
|
||||
parse_quote!(#crate_path::ext::sp_runtime::MultiAddress),
|
||||
),
|
||||
(
|
||||
"frame_support::traits::misc::WrapperKeepOpaque",
|
||||
parse_quote!(::subxt::utils::WrapperKeepOpaque),
|
||||
parse_quote!(#crate_path::utils::WrapperKeepOpaque),
|
||||
),
|
||||
// BTreeMap and BTreeSet impose an `Ord` constraint on their key types. This
|
||||
// can cause an issue with generated code that doesn't impl `Ord` by default.
|
||||
// Decoding them to Vec by default (KeyedVec is just an alias for Vec with
|
||||
// suitable type params) avoids these issues.
|
||||
("BTreeMap", parse_quote!(::subxt::utils::KeyedVec)),
|
||||
("BTreeMap", parse_quote!(#crate_path::utils::KeyedVec)),
|
||||
("BTreeSet", parse_quote!(::std::vec::Vec)),
|
||||
]
|
||||
.iter()
|
||||
@@ -161,6 +164,7 @@ impl RuntimeGenerator {
|
||||
"runtime_types",
|
||||
type_substitutes,
|
||||
derives.clone(),
|
||||
crate_path.clone(),
|
||||
);
|
||||
let types_mod = type_gen.generate_types_mod();
|
||||
let types_mod_ident = types_mod.ident();
|
||||
@@ -190,16 +194,23 @@ impl RuntimeGenerator {
|
||||
let metadata_hash = get_metadata_per_pallet_hash(&self.metadata, &pallet_names);
|
||||
|
||||
let modules = pallets_with_mod_names.iter().map(|(pallet, mod_name)| {
|
||||
let calls =
|
||||
calls::generate_calls(&self.metadata, &type_gen, pallet, types_mod_ident);
|
||||
let calls = calls::generate_calls(
|
||||
&self.metadata,
|
||||
&type_gen,
|
||||
pallet,
|
||||
types_mod_ident,
|
||||
&crate_path,
|
||||
);
|
||||
|
||||
let event = events::generate_events(&type_gen, pallet, types_mod_ident);
|
||||
let event =
|
||||
events::generate_events(&type_gen, pallet, types_mod_ident, &crate_path);
|
||||
|
||||
let storage_mod = storage::generate_storage(
|
||||
&self.metadata,
|
||||
&type_gen,
|
||||
pallet,
|
||||
types_mod_ident,
|
||||
&crate_path,
|
||||
);
|
||||
|
||||
let constants_mod = constants::generate_constants(
|
||||
@@ -207,6 +218,7 @@ impl RuntimeGenerator {
|
||||
&type_gen,
|
||||
pallet,
|
||||
types_mod_ident,
|
||||
&crate_path,
|
||||
);
|
||||
|
||||
quote! {
|
||||
@@ -338,6 +350,7 @@ pub fn generate_structs_from_variants<'a, F>(
|
||||
type_id: u32,
|
||||
variant_to_struct_name: F,
|
||||
error_message_type_name: &str,
|
||||
crate_path: &CratePath,
|
||||
) -> Vec<(String, CompositeDef)>
|
||||
where
|
||||
F: Fn(&str) -> std::borrow::Cow<str>,
|
||||
@@ -363,6 +376,7 @@ where
|
||||
Some(parse_quote!(pub)),
|
||||
type_gen,
|
||||
var.docs(),
|
||||
crate_path,
|
||||
);
|
||||
(var.name().to_string(), struct_def)
|
||||
})
|
||||
|
||||
+19
-12
@@ -2,7 +2,10 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::types::TypeGenerator;
|
||||
use crate::{
|
||||
types::TypeGenerator,
|
||||
CratePath,
|
||||
};
|
||||
use frame_metadata::{
|
||||
v14::RuntimeMetadataV14,
|
||||
PalletMetadata,
|
||||
@@ -37,6 +40,7 @@ pub fn generate_storage(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata<PortableForm>,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
) -> TokenStream2 {
|
||||
let storage = if let Some(ref storage) = pallet.storage {
|
||||
storage
|
||||
@@ -47,7 +51,9 @@ pub fn generate_storage(
|
||||
let storage_fns: Vec<_> = storage
|
||||
.entries
|
||||
.iter()
|
||||
.map(|entry| generate_storage_entry_fns(metadata, type_gen, pallet, entry))
|
||||
.map(|entry| {
|
||||
generate_storage_entry_fns(metadata, type_gen, pallet, entry, crate_path)
|
||||
})
|
||||
.collect();
|
||||
|
||||
quote! {
|
||||
@@ -68,6 +74,7 @@ fn generate_storage_entry_fns(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata<PortableForm>,
|
||||
storage_entry: &StorageEntryMetadata<PortableForm>,
|
||||
crate_path: &CratePath,
|
||||
) -> TokenStream2 {
|
||||
let (fields, key_impl) = match storage_entry.ty {
|
||||
StorageEntryType::Plain(_) => (vec![], quote!(vec![])),
|
||||
@@ -90,7 +97,7 @@ fn generate_storage_entry_fns(
|
||||
StorageHasher::Identity => "Identity",
|
||||
};
|
||||
let hasher = format_ident!("{}", hasher);
|
||||
quote!( ::subxt::storage::address::StorageHasher::#hasher )
|
||||
quote!( #crate_path::storage::address::StorageHasher::#hasher )
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
match key_ty.type_def() {
|
||||
@@ -114,7 +121,7 @@ fn generate_storage_entry_fns(
|
||||
.into_iter()
|
||||
.zip(&fields)
|
||||
.map(|(hasher, (field_name, _))| {
|
||||
quote!( ::subxt::storage::address::StorageMapKey::new(#field_name.borrow(), #hasher) )
|
||||
quote!( #crate_path::storage::address::StorageMapKey::new(#field_name.borrow(), #hasher) )
|
||||
});
|
||||
quote! {
|
||||
vec![ #( #keys ),* ]
|
||||
@@ -127,7 +134,7 @@ fn generate_storage_entry_fns(
|
||||
let items =
|
||||
fields.iter().map(|(field_name, _)| quote!( #field_name ));
|
||||
quote! {
|
||||
vec![ ::subxt::storage::address::StorageMapKey::new(&(#( #items.borrow() ),*), #hasher) ]
|
||||
vec![ #crate_path::storage::address::StorageMapKey::new(&(#( #items.borrow() ),*), #hasher) ]
|
||||
}
|
||||
} else {
|
||||
// If we hit this condition, we don't know how to handle the number of hashes vs fields
|
||||
@@ -148,7 +155,7 @@ fn generate_storage_entry_fns(
|
||||
abort_call_site!("No hasher found for single key")
|
||||
});
|
||||
let key_impl = quote! {
|
||||
vec![ ::subxt::storage::address::StorageMapKey::new(_0.borrow(), #hasher) ]
|
||||
vec![ #crate_path::storage::address::StorageMapKey::new(_0.borrow(), #hasher) ]
|
||||
};
|
||||
(fields, key_impl)
|
||||
}
|
||||
@@ -195,7 +202,7 @@ fn generate_storage_entry_fns(
|
||||
|
||||
// Is the entry iterable?
|
||||
let is_iterable_type = if is_map_type {
|
||||
quote!(::subxt::storage::address::Yes)
|
||||
quote!(#crate_path::storage::address::Yes)
|
||||
} else {
|
||||
quote!(())
|
||||
};
|
||||
@@ -207,7 +214,7 @@ fn generate_storage_entry_fns(
|
||||
|
||||
// Does the entry have a default value?
|
||||
let is_defaultable_type = if has_default_value {
|
||||
quote!(::subxt::storage::address::Yes)
|
||||
quote!(#crate_path::storage::address::Yes)
|
||||
} else {
|
||||
quote!(())
|
||||
};
|
||||
@@ -220,8 +227,8 @@ fn generate_storage_entry_fns(
|
||||
#docs_token
|
||||
pub fn #fn_name_root(
|
||||
&self,
|
||||
) -> ::subxt::storage::address::StaticStorageAddress::<::subxt::metadata::DecodeStaticType<#storage_entry_value_ty>, (), #is_defaultable_type, #is_iterable_type> {
|
||||
::subxt::storage::address::StaticStorageAddress::new(
|
||||
) -> #crate_path::storage::address::StaticStorageAddress::<#crate_path::metadata::DecodeStaticType<#storage_entry_value_ty>, (), #is_defaultable_type, #is_iterable_type> {
|
||||
#crate_path::storage::address::StaticStorageAddress::new(
|
||||
#pallet_name,
|
||||
#storage_name,
|
||||
Vec::new(),
|
||||
@@ -239,8 +246,8 @@ fn generate_storage_entry_fns(
|
||||
pub fn #fn_name(
|
||||
&self,
|
||||
#( #key_args, )*
|
||||
) -> ::subxt::storage::address::StaticStorageAddress::<::subxt::metadata::DecodeStaticType<#storage_entry_value_ty>, ::subxt::storage::address::Yes, #is_defaultable_type, #is_iterable_type> {
|
||||
::subxt::storage::address::StaticStorageAddress::new(
|
||||
) -> #crate_path::storage::address::StaticStorageAddress::<#crate_path::metadata::DecodeStaticType<#storage_entry_value_ty>, #crate_path::storage::address::Yes, #is_defaultable_type, #is_iterable_type> {
|
||||
#crate_path::storage::address::StaticStorageAddress::new(
|
||||
#pallet_name,
|
||||
#storage_name,
|
||||
#key_impl,
|
||||
|
||||
Reference in New Issue
Block a user