mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-22 11:27:58 +00:00
Use scale-encode and scale-decode to encode and decode based on metadata (#842)
* WIP EncodeAsType and DecodeAsType * remove silly cli experiment code * Get things finally compiling with EncodeAsType and DecodeAsType * update codegen test and WrapperKeepOpaque proper impl (in case it shows up in codegen) * fix tests * accomodate scale-value changes * starting to migrate to EncodeAsType/DecodeAsType * static event decoding and tx encoding to use DecodeAsFields/EncodeAsFields * some tidy up and add decode(skip) attrs where needed * fix root event decoding * #[codec(skip)] will do, and combine map_key stuff into storage_address since it's all specific to that * fmt and clippy * update Cargo.lock * remove patched scale-encode * bump scale-encode to 0.1 and remove unused dep in testing crate * update deps and use released scale-decode * update scale-value to latest to remove git branch * Apply suggestions from code review Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> * remove sorting in derives/attr generation; spit them out in order given * re-add derive sorting; it's a hashmap * StaticTxPayload and DynamicTxPayload rolled into single Payload struct * StaticStorageAddress and DynamicStorageAddress into single Address struct * Fix storage address byte retrieval * StaticConstantAddress and DynamicConstantAddress => Address * Simplify storage codegen to fix test * Add comments * Alias to RuntimeEvent rather than making another, and prep for substituting call type * remove unnecessary clone * Fix docs and failing UI test * root_bytes -> to_root_bytes * document error case in StorageClient::address_bytes() --------- Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
@@ -104,8 +104,8 @@ pub fn generate_calls(
|
||||
pub fn #fn_name(
|
||||
&self,
|
||||
#( #call_fn_args, )*
|
||||
) -> #crate_path::tx::StaticTxPayload<#struct_name> {
|
||||
#crate_path::tx::StaticTxPayload::new(
|
||||
) -> #crate_path::tx::Payload<#struct_name> {
|
||||
#crate_path::tx::Payload::new_static(
|
||||
#pallet_name,
|
||||
#call_name,
|
||||
#struct_name { #( #call_args, )* },
|
||||
|
||||
@@ -73,8 +73,8 @@ pub fn generate_constants(
|
||||
|
||||
Ok(quote! {
|
||||
#docs
|
||||
pub fn #fn_name(&self) -> #crate_path::constants::StaticConstantAddress<#crate_path::metadata::DecodeStaticType<#return_ty>> {
|
||||
#crate_path::constants::StaticConstantAddress::new(
|
||||
pub fn #fn_name(&self) -> #crate_path::constants::Address<#return_ty> {
|
||||
#crate_path::constants::Address::new_static(
|
||||
#pallet_name,
|
||||
#constant_name,
|
||||
[#(#constant_hash,)*]
|
||||
|
||||
+65
-32
@@ -53,6 +53,9 @@ use syn::parse_quote;
|
||||
/// Error returned when the Codegen cannot generate the runtime API.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum CodegenError {
|
||||
/// The given metadata type could not be found.
|
||||
#[error("Could not find type with ID {0} in the type registry; please raise a support issue.")]
|
||||
TypeNotFound(u32),
|
||||
/// Cannot fetch the metadata bytes.
|
||||
#[error("Failed to fetch metadata, make sure that you're pointing at a node which is providing V14 metadata: {0}")]
|
||||
Fetch(#[from] FetchMetadataError),
|
||||
@@ -80,12 +83,6 @@ pub enum CodegenError {
|
||||
/// Metadata for storage could not be found.
|
||||
#[error("Metadata for storage entry {0}_{1} could not be found. Make sure you are providing a valid metadata V14")]
|
||||
MissingStorageMetadata(String, String),
|
||||
/// StorageNMap should have N hashers.
|
||||
#[error("Number of hashers ({0}) does not equal 1 for StorageMap, or match number of fields ({1}) for StorageNMap. Make sure you are providing a valid metadata V14")]
|
||||
MismatchHashers(usize, usize),
|
||||
/// Expected to find one hasher for StorageMap.
|
||||
#[error("No hasher found for single key. Make sure you are providing a valid metadata V14")]
|
||||
MissingHasher,
|
||||
/// Metadata for call could not be found.
|
||||
#[error("Metadata for call entry {0}_{1} could not be found. Make sure you are providing a valid metadata V14")]
|
||||
MissingCallMetadata(String, String),
|
||||
@@ -319,13 +316,12 @@ impl RuntimeGenerator {
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let item_mod_attrs = item_mod.attrs.clone();
|
||||
let item_mod_ir = ir::ItemMod::try_from(item_mod)?;
|
||||
let default_derives = derives.default_derives();
|
||||
|
||||
let type_gen = TypeGenerator::new(
|
||||
&self.metadata.types,
|
||||
"runtime_types",
|
||||
type_substitutes,
|
||||
derives.clone(),
|
||||
derives,
|
||||
crate_path.clone(),
|
||||
should_gen_docs,
|
||||
);
|
||||
@@ -343,6 +339,28 @@ impl RuntimeGenerator {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Get the path to the `Runtime` struct. We assume that the same path contains
|
||||
// RuntimeCall and RuntimeEvent.
|
||||
let runtime_type_id = self.metadata.ty.id();
|
||||
let runtime_path_segments = self
|
||||
.metadata
|
||||
.types
|
||||
.resolve(runtime_type_id)
|
||||
.ok_or(CodegenError::TypeNotFound(runtime_type_id))?
|
||||
.path()
|
||||
.namespace()
|
||||
.iter()
|
||||
.map(|part| syn::PathSegment::from(format_ident!("{}", part)));
|
||||
let runtime_path_suffix = syn::Path {
|
||||
leading_colon: None,
|
||||
segments: syn::punctuated::Punctuated::from_iter(runtime_path_segments),
|
||||
};
|
||||
let runtime_path = if runtime_path_suffix.segments.is_empty() {
|
||||
quote!(#types_mod_ident)
|
||||
} else {
|
||||
quote!(#types_mod_ident::#runtime_path_suffix)
|
||||
};
|
||||
|
||||
// Pallet names and their length are used to create PALLETS array.
|
||||
// The array is used to identify the pallets composing the metadata for
|
||||
// validation of just those pallets.
|
||||
@@ -407,26 +425,24 @@ impl RuntimeGenerator {
|
||||
})
|
||||
.collect::<Result<Vec<_>, CodegenError>>()?;
|
||||
|
||||
let outer_event_variants = self.metadata.pallets.iter().filter_map(|p| {
|
||||
let variant_name = format_ident!("{}", p.name);
|
||||
let mod_name = format_ident!("{}", p.name.to_string().to_snake_case());
|
||||
let index = proc_macro2::Literal::u8_unsuffixed(p.index);
|
||||
|
||||
let root_event_if_arms = self.metadata.pallets.iter().filter_map(|p| {
|
||||
let variant_name_str = &p.name;
|
||||
let variant_name = format_ident!("{}", variant_name_str);
|
||||
let mod_name = format_ident!("{}", variant_name_str.to_string().to_snake_case());
|
||||
p.event.as_ref().map(|_| {
|
||||
// An 'if' arm for the RootEvent impl to match this variant name:
|
||||
quote! {
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#mod_name::Event),
|
||||
if pallet_name == #variant_name_str {
|
||||
return Ok(Event::#variant_name(#mod_name::Event::decode_with_metadata(
|
||||
&mut &*pallet_bytes,
|
||||
pallet_ty,
|
||||
metadata
|
||||
)?));
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let outer_event = quote! {
|
||||
#default_derives
|
||||
pub enum Event {
|
||||
#( #outer_event_variants )*
|
||||
}
|
||||
};
|
||||
|
||||
let mod_ident = &item_mod_ir.ident;
|
||||
let pallets_with_constants: Vec<_> = pallets_with_mod_names
|
||||
.iter()
|
||||
@@ -456,22 +472,36 @@ impl RuntimeGenerator {
|
||||
#[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
|
||||
// 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;
|
||||
// Make it easy to access the root items via `root_mod` at different levels
|
||||
// without reaching out of this module.
|
||||
#[allow(unused_imports)]
|
||||
mod root_mod {
|
||||
pub use super::*;
|
||||
}
|
||||
|
||||
// Identify the pallets composing the static metadata by name.
|
||||
pub static PALLETS: [&str; #pallet_names_len] = [ #(#pallet_names,)* ];
|
||||
|
||||
#outer_event
|
||||
#( #modules )*
|
||||
#types_mod
|
||||
/// The statically generated runtime call type.
|
||||
pub type Call = #runtime_path::RuntimeCall;
|
||||
|
||||
/// The default error type returned when there is a runtime issue,
|
||||
/// exposed here for ease of use.
|
||||
/// The error type returned when there is a runtime issue.
|
||||
pub type DispatchError = #types_mod_ident::sp_runtime::DispatchError;
|
||||
|
||||
// Make the runtime event type easily accessible, and impl RootEvent to help decode into it.
|
||||
pub type Event = #runtime_path::RuntimeEvent;
|
||||
|
||||
impl #crate_path::events::RootEvent for Event {
|
||||
fn root_event(pallet_bytes: &[u8], pallet_name: &str, pallet_ty: u32, metadata: &#crate_path::Metadata) -> Result<Self, #crate_path::Error> {
|
||||
use #crate_path::metadata::DecodeWithMetadata;
|
||||
#( #root_event_if_arms )*
|
||||
Err(#crate_path::ext::scale_decode::Error::custom(format!("Pallet name '{}' not found in root Event enum", pallet_name)).into())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn constants() -> ConstantsApi {
|
||||
ConstantsApi
|
||||
}
|
||||
@@ -512,14 +542,17 @@ impl RuntimeGenerator {
|
||||
}
|
||||
|
||||
/// check whether the Client you are using is aligned with the statically generated codegen.
|
||||
pub fn validate_codegen<T: ::subxt::Config, C: ::subxt::client::OfflineClientT<T>>(client: &C) -> Result<(), ::subxt::error::MetadataError> {
|
||||
pub fn validate_codegen<T: #crate_path::Config, C: #crate_path::client::OfflineClientT<T>>(client: &C) -> Result<(), #crate_path::error::MetadataError> {
|
||||
let runtime_metadata_hash = client.metadata().metadata_hash(&PALLETS);
|
||||
if runtime_metadata_hash != [ #(#metadata_hash,)* ] {
|
||||
Err(::subxt::error::MetadataError::IncompatibleMetadata)
|
||||
Err(#crate_path::error::MetadataError::IncompatibleMetadata)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#( #modules )*
|
||||
#types_mod
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+28
-59
@@ -12,7 +12,6 @@ use frame_metadata::{
|
||||
StorageEntryMetadata,
|
||||
StorageEntryModifier,
|
||||
StorageEntryType,
|
||||
StorageHasher,
|
||||
};
|
||||
use heck::ToSnakeCase as _;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
@@ -84,31 +83,12 @@ fn generate_storage_entry_fns(
|
||||
crate_path: &CratePath,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let (fields, key_impl) = match storage_entry.ty {
|
||||
let (fields, key_impl) = match &storage_entry.ty {
|
||||
StorageEntryType::Plain(_) => (vec![], quote!(vec![])),
|
||||
StorageEntryType::Map {
|
||||
ref key,
|
||||
ref hashers,
|
||||
..
|
||||
} => {
|
||||
StorageEntryType::Map { key, .. } => {
|
||||
let key_ty = type_gen.resolve_type(key.id());
|
||||
let hashers = hashers
|
||||
.iter()
|
||||
.map(|hasher| {
|
||||
let hasher = match hasher {
|
||||
StorageHasher::Blake2_128 => "Blake2_128",
|
||||
StorageHasher::Blake2_256 => "Blake2_256",
|
||||
StorageHasher::Blake2_128Concat => "Blake2_128Concat",
|
||||
StorageHasher::Twox128 => "Twox128",
|
||||
StorageHasher::Twox256 => "Twox256",
|
||||
StorageHasher::Twox64Concat => "Twox64Concat",
|
||||
StorageHasher::Identity => "Identity",
|
||||
};
|
||||
let hasher = format_ident!("{}", hasher);
|
||||
quote!( #crate_path::storage::address::StorageHasher::#hasher )
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
match key_ty.type_def() {
|
||||
// An N-map; return each of the keys separately.
|
||||
TypeDef::Tuple(tuple) => {
|
||||
let fields = tuple
|
||||
.fields()
|
||||
@@ -121,46 +101,23 @@ fn generate_storage_entry_fns(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let key_impl = if hashers.len() == fields.len() {
|
||||
// If the number of hashers matches the number of fields, we're dealing with
|
||||
// something shaped like a StorageNMap, and each field should be hashed separately
|
||||
// according to the corresponding hasher.
|
||||
let keys = hashers
|
||||
.into_iter()
|
||||
.zip(&fields)
|
||||
.map(|(hasher, (field_name, _))| {
|
||||
quote!( #crate_path::storage::address::StorageMapKey::new(#field_name.borrow(), #hasher) )
|
||||
});
|
||||
quote! {
|
||||
vec![ #( #keys ),* ]
|
||||
}
|
||||
} else if hashers.len() == 1 {
|
||||
// If there is one hasher, then however many fields we have, we want to hash a
|
||||
// tuple of them using the one hasher we're told about. This corresponds to a
|
||||
// StorageMap.
|
||||
let hasher = hashers.get(0).expect("checked for 1 hasher");
|
||||
let items =
|
||||
fields.iter().map(|(field_name, _)| quote!( #field_name ));
|
||||
quote! {
|
||||
vec![ #crate_path::storage::address::StorageMapKey::new(&(#( #items.borrow() ),*), #hasher) ]
|
||||
}
|
||||
} else {
|
||||
return Err(CodegenError::MismatchHashers(
|
||||
hashers.len(),
|
||||
fields.len(),
|
||||
))
|
||||
let keys = fields
|
||||
.iter()
|
||||
.map(|(field_name, _)| {
|
||||
quote!( #crate_path::storage::address::StaticStorageMapKey::new(#field_name.borrow()) )
|
||||
});
|
||||
let key_impl = quote! {
|
||||
vec![ #( #keys ),* ]
|
||||
};
|
||||
|
||||
(fields, key_impl)
|
||||
}
|
||||
// A map with a single key; return the single key.
|
||||
_ => {
|
||||
let ty_path = type_gen.resolve_type_path(key.id());
|
||||
let fields = vec![(format_ident!("_0"), ty_path)];
|
||||
let Some(hasher) = hashers.get(0) else {
|
||||
return Err(CodegenError::MissingHasher)
|
||||
};
|
||||
let key_impl = quote! {
|
||||
vec![ #crate_path::storage::address::StorageMapKey::new(_0.borrow(), #hasher) ]
|
||||
vec![ #crate_path::storage::address::StaticStorageMapKey::new(_0.borrow()) ]
|
||||
};
|
||||
(fields, key_impl)
|
||||
}
|
||||
@@ -233,8 +190,14 @@ fn generate_storage_entry_fns(
|
||||
#docs
|
||||
pub fn #fn_name_root(
|
||||
&self,
|
||||
) -> #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(
|
||||
) -> #crate_path::storage::address::Address::<
|
||||
#crate_path::storage::address::StaticStorageMapKey,
|
||||
#storage_entry_value_ty,
|
||||
(),
|
||||
#is_defaultable_type,
|
||||
#is_iterable_type
|
||||
> {
|
||||
#crate_path::storage::address::Address::new_static(
|
||||
#pallet_name,
|
||||
#storage_name,
|
||||
Vec::new(),
|
||||
@@ -252,8 +215,14 @@ fn generate_storage_entry_fns(
|
||||
pub fn #fn_name(
|
||||
&self,
|
||||
#( #key_args, )*
|
||||
) -> #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(
|
||||
) -> #crate_path::storage::address::Address::<
|
||||
#crate_path::storage::address::StaticStorageMapKey,
|
||||
#storage_entry_value_ty,
|
||||
#crate_path::storage::address::Yes,
|
||||
#is_defaultable_type,
|
||||
#is_iterable_type
|
||||
> {
|
||||
#crate_path::storage::address::Address::new_static(
|
||||
#pallet_name,
|
||||
#storage_name,
|
||||
#key_impl,
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
use crate::CratePath;
|
||||
use syn::{
|
||||
parse_quote,
|
||||
punctuated::Punctuated,
|
||||
Path,
|
||||
};
|
||||
|
||||
@@ -21,7 +20,7 @@ pub struct DerivesRegistry {
|
||||
}
|
||||
|
||||
impl DerivesRegistry {
|
||||
/// Creates a new `DeviceRegistry` with the supplied `crate_path`.
|
||||
/// Creates a new `DerivesRegistry` with the supplied `crate_path`.
|
||||
///
|
||||
/// The `crate_path` denotes the `subxt` crate access path in the
|
||||
/// generated code.
|
||||
@@ -61,23 +60,27 @@ impl DerivesRegistry {
|
||||
/// - Any user-defined derives for all types via `generated_type_derives`
|
||||
/// - Any user-defined derives for this specific type
|
||||
pub fn resolve(&self, ty: &syn::TypePath) -> Derives {
|
||||
let mut defaults = self.default_derives.derives.clone();
|
||||
let mut resolved_derives = self.default_derives.clone();
|
||||
if let Some(specific) = self.specific_type_derives.get(ty) {
|
||||
defaults.extend(specific.derives.iter().cloned());
|
||||
resolved_derives.extend_from(specific.clone());
|
||||
}
|
||||
Derives { derives: defaults }
|
||||
resolved_derives
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Derives {
|
||||
derives: HashSet<syn::Path>,
|
||||
attributes: HashSet<syn::Attribute>,
|
||||
}
|
||||
|
||||
impl FromIterator<syn::Path> for Derives {
|
||||
fn from_iter<T: IntoIterator<Item = Path>>(iter: T) -> Self {
|
||||
let derives = iter.into_iter().collect();
|
||||
Self { derives }
|
||||
Self {
|
||||
derives,
|
||||
attributes: HashSet::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,26 +89,55 @@ impl Derives {
|
||||
/// to the set of default derives that reside in `subxt`.
|
||||
pub fn new(crate_path: &CratePath) -> Self {
|
||||
let mut derives = HashSet::new();
|
||||
let mut attributes = HashSet::new();
|
||||
|
||||
derives.insert(syn::parse_quote!(#crate_path::ext::scale_encode::EncodeAsType));
|
||||
let encode_crate_path =
|
||||
quote::quote! { #crate_path::ext::scale_encode }.to_string();
|
||||
attributes.insert(
|
||||
syn::parse_quote!(#[encode_as_type(crate_path = #encode_crate_path)]),
|
||||
);
|
||||
derives.insert(syn::parse_quote!(#crate_path::ext::scale_decode::DecodeAsType));
|
||||
let decode_crate_path =
|
||||
quote::quote! { #crate_path::ext::scale_decode }.to_string();
|
||||
attributes.insert(
|
||||
syn::parse_quote!(#[decode_as_type(crate_path = #decode_crate_path)]),
|
||||
);
|
||||
|
||||
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 }
|
||||
|
||||
Self {
|
||||
derives,
|
||||
attributes,
|
||||
}
|
||||
}
|
||||
|
||||
/// Extend this set of `Derives` from another.
|
||||
pub fn extend_from(&mut self, other: Derives) {
|
||||
self.derives.extend(other.derives.into_iter());
|
||||
self.attributes.extend(other.attributes.into_iter());
|
||||
}
|
||||
|
||||
/// 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));
|
||||
self.insert_derive(parse_quote!(#crate_path::ext::codec::CompactAs));
|
||||
}
|
||||
|
||||
pub fn append(&mut self, derives: impl Iterator<Item = syn::Path>) {
|
||||
for derive in derives {
|
||||
self.insert(derive)
|
||||
self.insert_derive(derive)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, derive: syn::Path) {
|
||||
pub fn insert_derive(&mut self, derive: syn::Path) {
|
||||
self.derives.insert(derive);
|
||||
}
|
||||
|
||||
pub fn insert_attribute(&mut self, attribute: syn::Attribute) {
|
||||
self.attributes.insert(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
impl quote::ToTokens for Derives {
|
||||
@@ -117,10 +149,21 @@ impl quote::ToTokens for Derives {
|
||||
.to_string()
|
||||
.cmp("e::quote!(#b).to_string())
|
||||
});
|
||||
let derives: Punctuated<syn::Path, syn::Token![,]> =
|
||||
sorted.iter().cloned().collect();
|
||||
|
||||
tokens.extend(quote::quote! {
|
||||
#[derive(#derives)]
|
||||
#[derive(#( #sorted ),*)]
|
||||
})
|
||||
}
|
||||
if !self.attributes.is_empty() {
|
||||
let mut sorted = self.attributes.iter().cloned().collect::<Vec<_>>();
|
||||
sorted.sort_by(|a, b| {
|
||||
quote::quote!(#a)
|
||||
.to_string()
|
||||
.cmp("e::quote!(#b).to_string())
|
||||
});
|
||||
|
||||
tokens.extend(quote::quote! {
|
||||
#( #sorted )*
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,10 @@ pub use self::{
|
||||
Derives,
|
||||
DerivesRegistry,
|
||||
},
|
||||
substitutes::TypeSubstitutes,
|
||||
substitutes::{
|
||||
AbsolutePath,
|
||||
TypeSubstitutes,
|
||||
},
|
||||
type_def::TypeDefGen,
|
||||
type_def_params::TypeDefParameters,
|
||||
type_path::{
|
||||
|
||||
@@ -108,50 +108,79 @@ impl TypeSubstitutes {
|
||||
}
|
||||
}
|
||||
|
||||
/// Only insert the given substitution if a substitution at that path doesn't
|
||||
/// already exist.
|
||||
pub fn insert_if_not_exists(
|
||||
&mut self,
|
||||
source: syn::Path,
|
||||
target: AbsolutePath,
|
||||
) -> Result<(), CodegenError> {
|
||||
let (key, val) = TypeSubstitutes::parse_path_substitution(source, target.0)?;
|
||||
self.substitutes.entry(key).or_insert(val);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a bunch of source to target type substitutions.
|
||||
pub fn extend(
|
||||
&mut self,
|
||||
elems: impl IntoIterator<Item = (syn::Path, AbsolutePath)>,
|
||||
) -> Result<(), CodegenError> {
|
||||
let to_extend = elems.into_iter().map(|(path, AbsolutePath(mut with))| {
|
||||
let Some(syn::PathSegment { arguments: src_path_args, ..}) = path.segments.last() else {
|
||||
return Err(CodegenError::EmptySubstitutePath(path.span()))
|
||||
};
|
||||
let Some(syn::PathSegment { arguments: target_path_args, ..}) = with.segments.last_mut() else {
|
||||
return Err(CodegenError::EmptySubstitutePath(with.span()))
|
||||
};
|
||||
|
||||
let source_args: Vec<_> = type_args(src_path_args).collect();
|
||||
|
||||
let param_mapping = if source_args.is_empty() {
|
||||
// If the type parameters on the source type are not specified, then this means that
|
||||
// the type is either not generic or the user wants to pass through all the parameters
|
||||
TypeParamMapping::None
|
||||
} else {
|
||||
// Describe the mapping in terms of "which source param idx is used for each target param".
|
||||
// So, for each target param, find the matching source param index.
|
||||
let mapping = type_args(target_path_args)
|
||||
.filter_map(|arg|
|
||||
source_args
|
||||
.iter()
|
||||
.position(|&src| src == arg)
|
||||
.map(|src_idx|
|
||||
u8::try_from(src_idx).expect("type arguments to be fewer than 256; qed"),
|
||||
)
|
||||
).collect();
|
||||
TypeParamMapping::Specified(mapping)
|
||||
};
|
||||
|
||||
// NOTE: Params are late bound and held separately, so clear them
|
||||
// here to not mess pretty printing this path and params together
|
||||
*target_path_args = syn::PathArguments::None;
|
||||
|
||||
Ok((PathSegments::from(&path), Substitute { path: with, param_mapping }))
|
||||
}).collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
self.substitutes.extend(to_extend);
|
||||
for (source, target) in elems.into_iter() {
|
||||
let (key, val) = TypeSubstitutes::parse_path_substitution(source, target.0)?;
|
||||
self.substitutes.insert(key, val);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Given a source and target path, parse the type params to work out the mapping from
|
||||
/// source to target, and output the source => substitution mapping that we work out from this.
|
||||
fn parse_path_substitution(
|
||||
src_path: syn::Path,
|
||||
mut target_path: syn::Path,
|
||||
) -> Result<(PathSegments, Substitute), CodegenError> {
|
||||
let Some(syn::PathSegment { arguments: src_path_args, ..}) = src_path.segments.last() else {
|
||||
return Err(CodegenError::EmptySubstitutePath(src_path.span()))
|
||||
};
|
||||
let Some(syn::PathSegment { arguments: target_path_args, ..}) = target_path.segments.last_mut() else {
|
||||
return Err(CodegenError::EmptySubstitutePath(target_path.span()))
|
||||
};
|
||||
|
||||
let source_args: Vec<_> = type_args(src_path_args).collect();
|
||||
|
||||
let param_mapping = if source_args.is_empty() {
|
||||
// If the type parameters on the source type are not specified, then this means that
|
||||
// the type is either not generic or the user wants to pass through all the parameters
|
||||
TypeParamMapping::None
|
||||
} else {
|
||||
// Describe the mapping in terms of "which source param idx is used for each target param".
|
||||
// So, for each target param, find the matching source param index.
|
||||
let mapping = type_args(target_path_args)
|
||||
.filter_map(|arg| {
|
||||
source_args
|
||||
.iter()
|
||||
.position(|&src| src == arg)
|
||||
.map(|src_idx| {
|
||||
u8::try_from(src_idx)
|
||||
.expect("type arguments to be fewer than 256; qed")
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
TypeParamMapping::Specified(mapping)
|
||||
};
|
||||
|
||||
// Now that we've parsed the type params from our target path, remove said params from
|
||||
// that path, since we're storing them separately.
|
||||
*target_path_args = syn::PathArguments::None;
|
||||
|
||||
Ok((
|
||||
PathSegments::from(&src_path),
|
||||
Substitute {
|
||||
path: target_path,
|
||||
param_mapping,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// Given a source type path, return a substituted type path if a substitution is defined.
|
||||
pub fn for_path(&self, path: impl Into<PathSegments>) -> Option<&syn::Path> {
|
||||
self.substitutes.get(&path.into()).map(|s| &s.path)
|
||||
@@ -249,7 +278,7 @@ fn is_absolute(path: &syn::Path) -> bool {
|
||||
.map_or(false, |segment| segment.ident == "crate")
|
||||
}
|
||||
|
||||
pub struct AbsolutePath(syn::Path);
|
||||
pub struct AbsolutePath(pub syn::Path);
|
||||
|
||||
impl TryFrom<syn::Path> for AbsolutePath {
|
||||
type Error = (syn::Path, String);
|
||||
|
||||
+127
-43
@@ -57,7 +57,9 @@ fn generate_struct_with_primitives() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
pub a: ::core::primitive::bool,
|
||||
pub b: ::core::primitive::u32,
|
||||
@@ -106,12 +108,16 @@ fn generate_struct_with_a_struct_field() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Child {
|
||||
pub a: ::core::primitive::i32,
|
||||
}
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Parent {
|
||||
pub a: ::core::primitive::bool,
|
||||
pub b: root::subxt_codegen::types::tests::Child,
|
||||
@@ -154,10 +160,14 @@ fn generate_tuple_struct() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Child(pub ::core::primitive::i32,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Parent(pub ::core::primitive::bool, pub root::subxt_codegen::types::tests::Child,);
|
||||
}
|
||||
}
|
||||
@@ -239,34 +249,54 @@ fn derive_compact_as_for_uint_wrapper_structs() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Su128 { pub a: ::core::primitive::u128, }
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Su16 { pub a: ::core::primitive::u16, }
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Su32 { pub a: ::core::primitive::u32, }
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Su64 { pub a: ::core::primitive::u64, }
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Su8 { pub a: ::core::primitive::u8, }
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct TSu128(pub ::core::primitive::u128,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct TSu16(pub ::core::primitive::u16,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct TSu32(pub ::core::primitive::u32,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct TSu64(pub ::core::primitive::u64,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct TSu8(pub ::core::primitive::u8,);
|
||||
}
|
||||
}
|
||||
@@ -305,7 +335,9 @@ fn generate_enum() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub enum E {
|
||||
# [codec (index = 0)]
|
||||
A,
|
||||
@@ -366,7 +398,9 @@ fn compact_fields() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub enum E {
|
||||
# [codec (index = 0)]
|
||||
A {
|
||||
@@ -377,12 +411,16 @@ fn compact_fields() {
|
||||
B( #[codec(compact)] ::core::primitive::u32,),
|
||||
}
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
#[codec(compact)] pub a: ::core::primitive::u32,
|
||||
}
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct TupleStruct(#[codec(compact)] pub ::core::primitive::u32,);
|
||||
}
|
||||
}
|
||||
@@ -426,7 +464,9 @@ fn compact_generic_parameter() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
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 > >,
|
||||
@@ -469,7 +509,9 @@ fn generate_array_field() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
pub a: [::core::primitive::u8; 32usize],
|
||||
}
|
||||
@@ -509,7 +551,9 @@ fn option_fields() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
pub a: ::core::option::Option<::core::primitive::bool>,
|
||||
pub b: ::core::option::Option<::core::primitive::u32>,
|
||||
@@ -552,7 +596,9 @@ fn box_fields_struct() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
pub a: ::std::boxed::Box<::core::primitive::bool>,
|
||||
pub b: ::std::boxed::Box<::core::primitive::u32>,
|
||||
@@ -595,7 +641,9 @@ fn box_fields_enum() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub enum E {
|
||||
# [codec (index = 0)]
|
||||
A(::std::boxed::Box<::core::primitive::bool>,),
|
||||
@@ -638,7 +686,9 @@ fn range_fields() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
pub a: ::core::ops::Range<::core::primitive::u32>,
|
||||
pub b: ::core::ops::RangeInclusive<::core::primitive::u32>,
|
||||
@@ -685,12 +735,16 @@ fn generics() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
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_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Foo<_0> {
|
||||
pub a: _0,
|
||||
}
|
||||
@@ -736,12 +790,16 @@ fn generics_nested() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Bar<_0> {
|
||||
pub b: root::subxt_codegen::types::tests::Foo<_0, ::core::primitive::u32>,
|
||||
}
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Foo<_0, _1> {
|
||||
pub a: _0,
|
||||
pub b: ::core::option::Option<(_0, _1,)>,
|
||||
@@ -790,7 +848,9 @@ fn generate_bitvec() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct S {
|
||||
pub lsb: ::subxt_path::utils::bits::DecodedBits<::core::primitive::u8, ::subxt_path::utils::bits::Lsb0>,
|
||||
pub msb: ::subxt_path::utils::bits::DecodedBits<::core::primitive::u16, ::subxt_path::utils::bits::Msb0>,
|
||||
@@ -846,15 +906,21 @@ fn generics_with_alias_adds_phantom_data_marker() {
|
||||
quote! {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::CompactAs, ::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct NamedFields<_0> {
|
||||
pub b: ::core::primitive::u32,
|
||||
#[codec(skip)] pub __subxt_unused_type_params: ::core::marker::PhantomData<_0>
|
||||
#[codec(skip)]
|
||||
pub __subxt_unused_type_params: ::core::marker::PhantomData<_0>
|
||||
}
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct UnnamedFields<_0, _1> (
|
||||
pub (::core::primitive::u32, ::core::primitive::u32,),
|
||||
#[codec(skip)] pub ::core::marker::PhantomData<(_0, _1)>
|
||||
#[codec(skip)]
|
||||
pub ::core::marker::PhantomData<(_0, _1)>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -917,20 +983,26 @@ fn modules() {
|
||||
pub mod b {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Bar {
|
||||
pub a: root::subxt_codegen::types::tests::m::a::Foo,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Foo;
|
||||
}
|
||||
|
||||
pub mod c {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct Foo {
|
||||
pub a: root::subxt_codegen::types::tests::m::a::b::Bar,
|
||||
}
|
||||
@@ -970,7 +1042,9 @@ fn dont_force_struct_names_camel_case() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct AB;
|
||||
}
|
||||
}
|
||||
@@ -1014,10 +1088,14 @@ fn apply_user_defined_derives_for_all_types() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Clone, Debug, Eq)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Clone, Debug, Eq)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct A(pub root :: subxt_codegen :: types :: tests :: B,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Clone, Debug, Eq)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Clone, Debug, Eq)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct B;
|
||||
}
|
||||
}
|
||||
@@ -1082,13 +1160,19 @@ fn apply_user_defined_derives_for_specific_types() {
|
||||
pub mod tests {
|
||||
use super::root;
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug, Eq)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug, Eq)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct A(pub root :: subxt_codegen :: types :: tests :: B,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug, Eq, Hash)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug, Eq, Hash)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct B(pub root :: subxt_codegen :: types :: tests :: C,);
|
||||
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, Debug, Eq, Ord, PartialOrd)]
|
||||
#[derive(::subxt_path::ext::codec::Decode, ::subxt_path::ext::codec::Encode, ::subxt_path::ext::scale_decode::DecodeAsType, ::subxt_path::ext::scale_encode::EncodeAsType, Debug, Eq, Ord, PartialOrd)]
|
||||
#[decode_as_type(crate_path = ":: subxt_path :: ext :: scale_decode")]
|
||||
#[encode_as_type(crate_path = ":: subxt_path :: ext :: scale_encode")]
|
||||
pub struct C;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user