diff --git a/cli/src/main.rs b/cli/src/main.rs index 6ee42f1ff0e..930ff2a83f5 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -91,6 +91,10 @@ enum Command { /// Additional derives #[structopt(long = "derive")] derives: Vec, + /// The `subxt` crate access path in the generated code. + /// Defaults to `::subxt`. + #[structopt(short = "crate")] + crate_path: Option, }, /// Verify metadata compatibility between substrate nodes. Compatibility { @@ -136,7 +140,12 @@ async fn main() -> color_eyre::Result<()> { } } } - Command::Codegen { url, file, derives } => { + Command::Codegen { + url, + file, + derives, + crate_path, + } => { if let Some(file) = file.as_ref() { if url.is_some() { eyre::bail!("specify one of `--url` or `--file` but not both") @@ -145,7 +154,7 @@ async fn main() -> color_eyre::Result<()> { let mut file = fs::File::open(file)?; let mut bytes = Vec::new(); file.read_to_end(&mut bytes)?; - codegen(&mut &bytes[..], derives)?; + codegen(&mut &bytes[..], derives, crate_path)?; return Ok(()) } @@ -155,7 +164,7 @@ async fn main() -> color_eyre::Result<()> { .expect("default url is valid") }); let (_, bytes) = fetch_metadata(&url).await?; - codegen(&mut &bytes[..], derives)?; + codegen(&mut &bytes[..], derives, crate_path)?; Ok(()) } Command::Compatibility { nodes, pallet } => { @@ -296,6 +305,7 @@ async fn fetch_metadata(url: &Uri) -> color_eyre::Result<(String, Vec)> { fn codegen( encoded: &mut I, raw_derives: Vec, + crate_path: Option, ) -> color_eyre::Result<()> { let metadata = ::decode(encoded)?; let generator = subxt_codegen::RuntimeGenerator::new(metadata); @@ -307,10 +317,12 @@ fn codegen( .iter() .map(|raw| syn::parse_str(raw)) .collect::, _>>()?; - let mut derives = DerivesRegistry::default(); + + let crate_path = crate_path.map(Into::into).unwrap_or_default(); + let mut derives = DerivesRegistry::new(&crate_path); derives.extend_for_all(p.into_iter()); - let runtime_api = generator.generate_runtime(item_mod, derives); + let runtime_api = generator.generate_runtime(item_mod, derives, crate_path); println!("{}", runtime_api); Ok(()) } diff --git a/codegen/src/api/calls.rs b/codegen/src/api/calls.rs index 4fa13388e94..9b0cbfe97f3 100644 --- a/codegen/src/api/calls.rs +++ b/codegen/src/api/calls.rs @@ -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, 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, )* }, diff --git a/codegen/src/api/constants.rs b/codegen/src/api/constants.rs index 529da750599..73ef80b134f 100644 --- a/codegen/src/api/constants.rs +++ b/codegen/src/api/constants.rs @@ -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, 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,)*] diff --git a/codegen/src/api/events.rs b/codegen/src/api/events.rs index 24f0e380593..4ddecd935e8 100644 --- a/codegen/src/api/events.rs +++ b/codegen/src/api/events.rs @@ -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, 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; } diff --git a/codegen/src/api/mod.rs b/codegen/src/api/mod.rs index e97a9a38ac6..9b1530bb1bd 100644 --- a/codegen/src/api/mod.rs +++ b/codegen/src/api/mod.rs @@ -19,6 +19,7 @@ use crate::{ CompositeDefFields, TypeGenerator, }, + CratePath, }; use codec::Decode; use frame_metadata::{ @@ -55,6 +56,7 @@ pub fn generate_runtime_api

( item_mod: syn::ItemMod, path: P, derives: DerivesRegistry, + crate_path: CratePath, ) -> TokenStream2 where P: AsRef, @@ -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, @@ -363,6 +376,7 @@ where Some(parse_quote!(pub)), type_gen, var.docs(), + crate_path, ); (var.name().to_string(), struct_def) }) diff --git a/codegen/src/api/storage.rs b/codegen/src/api/storage.rs index 273cdb22b23..2168abe7600 100644 --- a/codegen/src/api/storage.rs +++ b/codegen/src/api/storage.rs @@ -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, 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, storage_entry: &StorageEntryMetadata, + 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::>(); 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, diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index c75e2c7b2a5..0a58906f687 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -21,7 +21,7 @@ //! use std::fs; //! use codec::Decode; //! use frame_metadata::RuntimeMetadataPrefixed; -//! use subxt_codegen::DerivesRegistry; +//! use subxt_codegen::{CratePath, DerivesRegistry}; //! //! let encoded = fs::read("../artifacts/polkadot_metadata.scale").unwrap(); //! @@ -32,10 +32,10 @@ //! pub mod api {} //! ); //! // Default module derivatives. -//! let mut derives = DerivesRegistry::default(); +//! let mut derives = DerivesRegistry::new(&CratePath::default()); //! // Generate the Runtime API. //! let generator = subxt_codegen::RuntimeGenerator::new(metadata); -//! let runtime_api = generator.generate_runtime(item_mod, derives); +//! let runtime_api = generator.generate_runtime(item_mod, derives, CratePath::default()); //! println!("{}", runtime_api); //! ``` @@ -51,6 +51,7 @@ pub use self::{ RuntimeGenerator, }, types::{ + CratePath, Derives, DerivesRegistry, Module, diff --git a/codegen/src/types/composite_def.rs b/codegen/src/types/composite_def.rs index 7d4dec5fc6f..7d6af13af4d 100644 --- a/codegen/src/types/composite_def.rs +++ b/codegen/src/types/composite_def.rs @@ -3,6 +3,7 @@ // see LICENSE for license details. use super::{ + CratePath, Derives, Field, TypeDefParameters, @@ -41,6 +42,7 @@ pub struct CompositeDef { impl CompositeDef { /// Construct a definition which will generate code for a standalone `struct`. + #[allow(clippy::too_many_arguments)] pub fn struct_def( ty: &Type, ident: &str, @@ -49,6 +51,7 @@ impl CompositeDef { field_visibility: Option, type_gen: &TypeGenerator, docs: &[String], + crate_path: &CratePath, ) -> Self { let mut derives = type_gen.type_derives(ty); let fields: Vec<_> = fields_def.field_types().collect(); @@ -73,7 +76,7 @@ impl CompositeDef { | TypeDefPrimitive::U128 ) ) { - derives.insert_codec_compact_as() + derives.insert_codec_compact_as(crate_path) } } } diff --git a/codegen/src/types/derives.rs b/codegen/src/types/derives.rs index 7ae2a180b93..0bfc6d9e17c 100644 --- a/codegen/src/types/derives.rs +++ b/codegen/src/types/derives.rs @@ -2,6 +2,7 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. +use crate::CratePath; use syn::{ parse_quote, punctuated::Punctuated, @@ -13,13 +14,24 @@ use std::collections::{ HashSet, }; -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct DerivesRegistry { default_derives: Derives, specific_type_derives: HashMap, } impl DerivesRegistry { + /// Creates a new `DeviceRegistry` with the supplied `crate_path`. + /// + /// The `crate_path` denotes the `subxt` crate access path in the + /// generated code. + pub fn new(crate_path: &CratePath) -> Self { + Self { + default_derives: Derives::new(crate_path), + specific_type_derives: Default::default(), + } + } + /// Insert derives to be applied to all generated types. pub fn extend_for_all(&mut self, derives: impl IntoIterator) { self.default_derives.derives.extend(derives) @@ -30,11 +42,12 @@ impl DerivesRegistry { &mut self, ty: syn::TypePath, derives: impl IntoIterator, + crate_path: &CratePath, ) { let type_derives = self .specific_type_derives .entry(ty) - .or_insert_with(Derives::default); + .or_insert_with(|| Derives::new(crate_path)); type_derives.derives.extend(derives) } @@ -69,9 +82,19 @@ impl FromIterator for Derives { } impl Derives { - /// Add `::subxt::ext::codec::CompactAs` to the derives. - pub fn insert_codec_compact_as(&mut self) { - self.insert(parse_quote!(::subxt::ext::codec::CompactAs)); + /// Creates a new instance of `Derives` with the `crate_path` prepended + /// to the set of default derives that reside in `subxt`. + pub fn new(crate_path: &CratePath) -> Self { + let mut derives = HashSet::new(); + derives.insert(syn::parse_quote!(#crate_path::ext::codec::Encode)); + derives.insert(syn::parse_quote!(#crate_path::ext::codec::Decode)); + derives.insert(syn::parse_quote!(Debug)); + Self { derives } + } + + /// Add `#crate_path::ext::codec::CompactAs` to the derives. + pub fn insert_codec_compact_as(&mut self, crate_path: &CratePath) { + self.insert(parse_quote!(#crate_path::ext::codec::CompactAs)); } pub fn append(&mut self, derives: impl Iterator) { @@ -85,16 +108,6 @@ impl Derives { } } -impl Default for Derives { - fn default() -> Self { - let mut derives = HashSet::new(); - derives.insert(syn::parse_quote!(::subxt::ext::codec::Encode)); - derives.insert(syn::parse_quote!(::subxt::ext::codec::Decode)); - derives.insert(syn::parse_quote!(Debug)); - Self { derives } - } -} - impl quote::ToTokens for Derives { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { if !self.derives.is_empty() { diff --git a/codegen/src/types/mod.rs b/codegen/src/types/mod.rs index 8e8a2b6fb15..f2950ab5d98 100644 --- a/codegen/src/types/mod.rs +++ b/codegen/src/types/mod.rs @@ -10,6 +10,7 @@ mod type_def; mod type_def_params; mod type_path; +use darling::FromMeta; use proc_macro2::{ Ident, Span, @@ -63,6 +64,8 @@ pub struct TypeGenerator<'a> { type_substitutes: HashMap, /// Set of derives with which to annotate generated types. derives: DerivesRegistry, + /// The `subxt` crate access path in the generated code. + crate_path: CratePath, } impl<'a> TypeGenerator<'a> { @@ -72,6 +75,7 @@ impl<'a> TypeGenerator<'a> { root_mod: &'static str, type_substitutes: HashMap, derives: DerivesRegistry, + crate_path: CratePath, ) -> Self { let root_mod_ident = Ident::new(root_mod, Span::call_site()); Self { @@ -79,6 +83,7 @@ impl<'a> TypeGenerator<'a> { type_registry, type_substitutes, derives, + crate_path, } } @@ -126,9 +131,10 @@ impl<'a> TypeGenerator<'a> { .or_insert_with(|| Module::new(mod_ident, root_mod_ident.clone())); if path.len() == 1 { - child_mod - .types - .insert(ty.path().clone(), TypeDefGen::from_type(ty, self)); + child_mod.types.insert( + ty.path().clone(), + TypeDefGen::from_type(ty, self, &self.crate_path), + ); } else { self.insert_type(ty, id, path[1..].to_vec(), root_mod_ident, child_mod) } @@ -279,6 +285,7 @@ impl<'a> TypeGenerator<'a> { parent_type_params, )), is_field, + crate_path: self.crate_path.clone(), } } TypeDef::BitSequence(bitseq) => { @@ -293,6 +300,7 @@ impl<'a> TypeGenerator<'a> { false, parent_type_params, )), + crate_path: self.crate_path.clone(), } } }; @@ -358,3 +366,57 @@ impl Module { &self.name } } + +#[derive(Debug, Clone)] +pub struct CratePath(syn::Path); + +impl CratePath { + /// Create a new `CratePath` from a `syn::Path`. + pub fn new(path: syn::Path) -> Self { + Self(path) + } +} + +impl Default for CratePath { + fn default() -> Self { + Self(syn::parse_quote!(::subxt)) + } +} + +impl From for CratePath { + fn from(path: syn::Path) -> Self { + CratePath::new(path) + } +} + +impl ToTokens for CratePath { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.0.to_tokens(tokens) + } +} + +impl From<&str> for CratePath { + fn from(crate_path: &str) -> Self { + Self(syn::Path::from_string(crate_path).unwrap_or_else(|err| { + panic!( + "failed converting {:?} to `syn::Path`: {:?}", + crate_path, err + ); + })) + } +} + +impl From for CratePath { + fn from(crate_path: String) -> Self { + CratePath::from(crate_path.as_str()) + } +} + +impl From> for CratePath { + fn from(maybe_crate_path: Option) -> Self { + match maybe_crate_path { + None => CratePath::default(), + Some(crate_path) => crate_path.into(), + } + } +} diff --git a/codegen/src/types/tests.rs b/codegen/src/types/tests.rs index 8dbfac0b3ad..c2949d476f2 100644 --- a/codegen/src/types/tests.rs +++ b/codegen/src/types/tests.rs @@ -43,7 +43,8 @@ fn generate_struct_with_primitives() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -54,7 +55,7 @@ fn generate_struct_with_primitives() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { pub a: ::core::primitive::bool, pub b: ::core::primitive::u32, @@ -89,7 +90,8 @@ fn generate_struct_with_a_struct_field() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -100,12 +102,12 @@ fn generate_struct_with_a_struct_field() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Child { pub a: ::core::primitive::i32, } - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Parent { pub a: ::core::primitive::bool, pub b: root::subxt_codegen::types::tests::Child, @@ -134,7 +136,8 @@ fn generate_tuple_struct() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -145,10 +148,10 @@ fn generate_tuple_struct() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Child(pub ::core::primitive::i32,); - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Parent(pub ::core::primitive::bool, pub root::subxt_codegen::types::tests::Child,); } } @@ -216,7 +219,8 @@ fn derive_compact_as_for_uint_wrapper_structs() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -227,34 +231,34 @@ fn derive_compact_as_for_uint_wrapper_structs() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Su128 { pub a: ::core::primitive::u128, } - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Su16 { pub a: ::core::primitive::u16, } - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Su32 { pub a: ::core::primitive::u32, } - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Su64 { pub a: ::core::primitive::u64, } - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Su8 { pub a: ::core::primitive::u8, } - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct TSu128(pub ::core::primitive::u128,); - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct TSu16(pub ::core::primitive::u16,); - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct TSu32(pub ::core::primitive::u32,); - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct TSu64(pub ::core::primitive::u64,); - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct TSu8(pub ::core::primitive::u8,); } } @@ -280,7 +284,8 @@ fn generate_enum() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -290,7 +295,7 @@ fn generate_enum() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub enum E { # [codec (index = 0)] A, @@ -338,7 +343,8 @@ fn compact_fields() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -348,7 +354,7 @@ fn compact_fields() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub enum E { # [codec (index = 0)] A { @@ -359,12 +365,12 @@ fn compact_fields() { B( #[codec(compact)] ::core::primitive::u32,), } - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { #[codec(compact)] pub a: ::core::primitive::u32, } - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct TupleStruct(#[codec(compact)] pub ::core::primitive::u32,); } } @@ -394,7 +400,8 @@ fn compact_generic_parameter() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -405,13 +412,13 @@ fn compact_generic_parameter() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { - pub a: ::core::option::Option<::subxt::ext::codec::Compact<::core::primitive::u128> >, - pub nested: ::core::option::Option<::core::result::Result<::subxt::ext::codec::Compact<::core::primitive::u128>, ::core::primitive::u8 > >, - pub vector: ::std::vec::Vec<::subxt::ext::codec::Compact<::core::primitive::u16> >, - pub array: [::subxt::ext::codec::Compact<::core::primitive::u8>; 32usize], - pub tuple: (::subxt::ext::codec::Compact<::core::primitive::u8>, ::subxt::ext::codec::Compact<::core::primitive::u16>,), + pub a: ::core::option::Option<::subxt_path::ext::codec::Compact<::core::primitive::u128> >, + pub nested: ::core::option::Option<::core::result::Result<::subxt_path::ext::codec::Compact<::core::primitive::u128>, ::core::primitive::u8 > >, + pub vector: ::std::vec::Vec<::subxt_path::ext::codec::Compact<::core::primitive::u16> >, + pub array: [::subxt_path::ext::codec::Compact<::core::primitive::u8>; 32usize], + pub tuple: (::subxt_path::ext::codec::Compact<::core::primitive::u8>, ::subxt_path::ext::codec::Compact<::core::primitive::u16>,), } } } @@ -435,7 +442,8 @@ fn generate_array_field() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -445,7 +453,7 @@ fn generate_array_field() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { pub a: [::core::primitive::u8; 32usize], } @@ -472,7 +480,8 @@ fn option_fields() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -482,7 +491,7 @@ fn option_fields() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { pub a: ::core::option::Option<::core::primitive::bool>, pub b: ::core::option::Option<::core::primitive::u32>, @@ -512,7 +521,8 @@ fn box_fields_struct() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -522,7 +532,7 @@ fn box_fields_struct() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { pub a: ::std::boxed::Box<::core::primitive::bool>, pub b: ::std::boxed::Box<::core::primitive::u32>, @@ -552,7 +562,8 @@ fn box_fields_enum() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -562,7 +573,7 @@ fn box_fields_enum() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub enum E { # [codec (index = 0)] A(::std::boxed::Box<::core::primitive::bool>,), @@ -592,7 +603,8 @@ fn range_fields() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -602,7 +614,7 @@ fn range_fields() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { pub a: ::core::ops::Range<::core::primitive::u32>, pub b: ::core::ops::RangeInclusive<::core::primitive::u32>, @@ -636,7 +648,8 @@ fn generics() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -646,12 +659,12 @@ fn generics() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Bar { pub b: root::subxt_codegen::types::tests::Foo<::core::primitive::u32>, pub c: root::subxt_codegen::types::tests::Foo<::core::primitive::u8>, } - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Foo<_0> { pub a: _0, } @@ -684,7 +697,8 @@ fn generics_nested() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -694,12 +708,12 @@ fn generics_nested() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Bar<_0> { pub b: root::subxt_codegen::types::tests::Foo<_0, ::core::primitive::u32>, } - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Foo<_0, _1> { pub a: _0, pub b: ::core::option::Option<(_0, _1,)>, @@ -735,7 +749,8 @@ fn generate_bitvec() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -745,10 +760,10 @@ fn generate_bitvec() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct S { - pub lsb: ::subxt::ext::bitvec::vec::BitVec<::core::primitive::u8, root::bitvec::order::Lsb0>, - pub msb: ::subxt::ext::bitvec::vec::BitVec<::core::primitive::u16, root::bitvec::order::Msb0>, + pub lsb: ::subxt_path::ext::bitvec::vec::BitVec<::core::primitive::u8, root::bitvec::order::Lsb0>, + pub msb: ::subxt_path::ext::bitvec::vec::BitVec<::core::primitive::u16, root::bitvec::order::Msb0>, } } } @@ -788,7 +803,8 @@ fn generics_with_alias_adds_phantom_data_marker() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -798,12 +814,12 @@ fn generics_with_alias_adds_phantom_data_marker() { quote! { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::CompactAs, ::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct NamedFields<_0> { pub b: ::core::primitive::u32, #[codec(skip)] pub __subxt_unused_type_params: ::core::marker::PhantomData<_0> } - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct UnnamedFields<_0, _1> ( pub (::core::primitive::u32, ::core::primitive::u32,), #[codec(skip)] pub ::core::marker::PhantomData<(_0, _1)> @@ -848,7 +864,8 @@ fn modules() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -866,20 +883,20 @@ fn modules() { pub mod b { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Bar { pub a: root::subxt_codegen::types::tests::m::a::Foo, } } - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Foo; } pub mod c { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct Foo { pub a: root::subxt_codegen::types::tests::m::a::b::Bar, } @@ -905,7 +922,8 @@ fn dont_force_struct_names_camel_case() { &portable_types, "root", Default::default(), - Default::default(), + DerivesRegistry::new(&"::subxt_path".into()), + "::subxt_path".into(), ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -916,7 +934,7 @@ fn dont_force_struct_names_camel_case() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)] pub struct AB; } } @@ -939,11 +957,16 @@ fn apply_user_defined_derives_for_all_types() { let portable_types: PortableRegistry = registry.into(); // configure derives - let mut derives = DerivesRegistry::default(); + let mut derives = DerivesRegistry::new(&"::subxt_path".into()); derives.extend_for_all(vec![parse_quote!(Clone), parse_quote!(Eq)]); - let type_gen = - TypeGenerator::new(&portable_types, "root", Default::default(), derives); + let type_gen = TypeGenerator::new( + &portable_types, + "root", + Default::default(), + derives, + "::subxt_path".into(), + ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -953,10 +976,10 @@ fn apply_user_defined_derives_for_all_types() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Clone, Debug, Eq)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Clone, Debug, Eq)] pub struct A(pub root :: subxt_codegen :: types :: tests :: B,); - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Clone, Debug, Eq)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Clone, Debug, Eq)] pub struct B; } } @@ -983,13 +1006,14 @@ fn apply_user_defined_derives_for_specific_types() { let portable_types: PortableRegistry = registry.into(); // configure derives - let mut derives = DerivesRegistry::default(); + let mut derives = DerivesRegistry::new(&"::subxt_path".into()); // for all types derives.extend_for_all(vec![parse_quote!(Eq)]); // for specific types derives.extend_for_type( parse_quote!(subxt_codegen::types::tests::B), vec![parse_quote!(Hash)], + &"::subxt_path".into(), ); // duplicates (in this case `Eq`) will be combined (i.e. a set union) derives.extend_for_type( @@ -999,10 +1023,16 @@ fn apply_user_defined_derives_for_specific_types() { parse_quote!(Ord), parse_quote!(PartialOrd), ], + &"::subxt_path".into(), ); - let type_gen = - TypeGenerator::new(&portable_types, "root", Default::default(), derives); + let type_gen = TypeGenerator::new( + &portable_types, + "root", + Default::default(), + derives, + "::subxt_path".into(), + ); let types = type_gen.generate_types_mod(); let tests_mod = get_mod(&types, MOD_PATH).unwrap(); @@ -1012,13 +1042,13 @@ fn apply_user_defined_derives_for_specific_types() { pub mod tests { use super::root; - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug, Eq)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug, Eq)] pub struct A(pub root :: subxt_codegen :: types :: tests :: B,); - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug, Eq, Hash)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug, Eq, Hash)] pub struct B(pub root :: subxt_codegen :: types :: tests :: C,); - #[derive(::subxt::ext::codec::Decode, ::subxt::ext::codec::Encode, Debug, Eq, Ord, PartialOrd)] + #[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug, Eq, Ord, PartialOrd)] pub struct C; } } diff --git a/codegen/src/types/type_def.rs b/codegen/src/types/type_def.rs index b5043e071e8..3ca025cf009 100644 --- a/codegen/src/types/type_def.rs +++ b/codegen/src/types/type_def.rs @@ -5,6 +5,7 @@ use super::{ CompositeDef, CompositeDefFields, + CratePath, Derives, TypeDefParameters, TypeGenerator, @@ -40,7 +41,11 @@ pub struct TypeDefGen { impl TypeDefGen { /// Construct a type definition for codegen from the given [`scale_info::Type`]. - pub fn from_type(ty: Type, type_gen: &TypeGenerator) -> Self { + pub fn from_type( + ty: Type, + type_gen: &TypeGenerator, + crate_path: &CratePath, + ) -> Self { let derives = type_gen.type_derives(&ty); let type_params = ty @@ -82,6 +87,7 @@ impl TypeDefGen { Some(parse_quote!(pub)), type_gen, ty.docs(), + crate_path, ); TypeDefGenKind::Struct(composite_def) } diff --git a/codegen/src/types/type_path.rs b/codegen/src/types/type_path.rs index 74c31b3e1c6..4c26821e728 100644 --- a/codegen/src/types/type_path.rs +++ b/codegen/src/types/type_path.rs @@ -2,6 +2,8 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. +use crate::CratePath; + use proc_macro2::{ Ident, TokenStream, @@ -96,10 +98,12 @@ pub enum TypePathType { Compact { inner: Box, is_field: bool, + crate_path: CratePath, }, BitVec { bit_order_type: Box, bit_store_type: Box, + crate_path: CratePath, }, } @@ -170,6 +174,7 @@ impl TypePathType { TypePathType::BitVec { bit_order_type, bit_store_type, + crate_path: _, } => { bit_order_type.parent_type_params(acc); bit_store_type.parent_type_params(acc); @@ -222,21 +227,26 @@ impl TypePathType { TypeDefPrimitive::I256 => unimplemented!("not a rust primitive"), }) } - TypePathType::Compact { inner, is_field } => { + TypePathType::Compact { + inner, + is_field, + crate_path, + } => { let path = if *is_field { // compact fields can use the inner compact type directly and be annotated with // the `compact` attribute e.g. `#[codec(compact)] my_compact_field: u128` parse_quote! ( #inner ) } else { - parse_quote! ( ::subxt::ext::codec::Compact<#inner> ) + parse_quote! ( #crate_path::ext::codec::Compact<#inner> ) }; syn::Type::Path(path) } TypePathType::BitVec { bit_order_type, bit_store_type, + crate_path, } => { - let type_path = parse_quote! { ::subxt::ext::bitvec::vec::BitVec<#bit_store_type, #bit_order_type> }; + let type_path = parse_quote! { #crate_path::ext::bitvec::vec::BitVec<#bit_store_type, #bit_order_type> }; syn::Type::Path(type_path) } } diff --git a/macro/src/lib.rs b/macro/src/lib.rs index 100260733d3..28612786e4b 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -74,6 +74,16 @@ //! )] //! 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)] @@ -95,6 +105,8 @@ struct RuntimeMetadataArgs { derive_for_all_types: Option>, #[darling(multiple)] derive_for_type: Vec, + #[darling(default, rename = "crate")] + crate_path: Option, } #[derive(Debug, FromMeta)] @@ -118,14 +130,22 @@ pub fn subxt(args: TokenStream, input: TokenStream) -> TokenStream { let root_path = std::path::Path::new(&root); let path = root_path.join(args.runtime_metadata_path); - let mut derives_registry = DerivesRegistry::default(); + 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()) + derives_registry.extend_for_type( + derives.ty.clone(), + derives.derive.iter().cloned(), + &crate_path, + ) } - subxt_codegen::generate_runtime_api(item_mod, &path, derives_registry).into() + subxt_codegen::generate_runtime_api(item_mod, &path, derives_registry, crate_path) + .into() } diff --git a/testing/integration-tests/src/codegen/codegen_documentation.rs b/testing/integration-tests/src/codegen/codegen_documentation.rs index 86a0b3e7640..998d148fad6 100644 --- a/testing/integration-tests/src/codegen/codegen_documentation.rs +++ b/testing/integration-tests/src/codegen/codegen_documentation.rs @@ -4,6 +4,7 @@ use regex::Regex; use subxt_codegen::{ + CratePath, DerivesRegistry, RuntimeGenerator, }; @@ -42,7 +43,7 @@ fn metadata_docs() -> Vec { docs } -fn generate_runtime_interface() -> String { +fn generate_runtime_interface(crate_path: CratePath) -> String { // Load the runtime metadata downloaded from a node via `test-runtime`. let bytes = test_runtime::METADATA; let metadata: frame_metadata::RuntimeMetadataPrefixed = @@ -53,14 +54,16 @@ fn generate_runtime_interface() -> String { let item_mod = syn::parse_quote!( pub mod api {} ); - let derives = DerivesRegistry::default(); - generator.generate_runtime(item_mod, derives).to_string() + let derives = DerivesRegistry::new(&crate_path); + generator + .generate_runtime(item_mod, derives, crate_path) + .to_string() } fn interface_docs() -> Vec { // Generate the runtime interface from the node's metadata. // Note: the API is generated on a single line. - let runtime_api = generate_runtime_interface(); + let runtime_api = generate_runtime_interface(CratePath::default()); // Documentation lines have the following format: // # [ doc = "Upward message is invalid XCM."]