mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 14:41:11 +00:00
Implement a proper generic resolution in decl_storage! (#2913)
* Add failing test case * move storage maps to blake2_128 (#2268) * remove default hash, introduce twox_128 and blake2 * use blake2_128 & create ext_blake2_128 * refactor code * add benchmark * factorize generator * fix * parameterizable hasher * some fix * fix * fix * fix * metadata * fix * remove debug print * map -> blake2_256 * fix test * fix test * Apply suggestions from code review Co-Authored-By: thiolliere <gui.thiolliere@gmail.com> * impl twox 128 concat (#2353) * impl twox_128_concat * comment addressed * fix * impl twox_128->64_concat * fix test * Fix compilation and cleanup some docs * Lol * Remove traits from storage types that are not generic * Get instance test almost working as wanted * Make `srml-support-test` compile again :) * Fixes test of srml-support * Fix compilation * Break some lines * Remove incorrect macro match arm * Integrates review feedback * Update documentation * Fix compilation
This commit is contained in:
@@ -14,11 +14,13 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use syn;
|
||||
use quote::quote;
|
||||
use crate::storage::transformation::{DeclStorageTypeInfos, InstanceOpts};
|
||||
|
||||
use srml_support_procedural_tools::syn_ext as ext;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use syn::Ident;
|
||||
use quote::quote;
|
||||
|
||||
pub fn option_unwrap(is_option: bool) -> TokenStream2 {
|
||||
if !is_option {
|
||||
// raw type case
|
||||
@@ -79,7 +81,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
};
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -87,20 +88,37 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
} = instance_opts;
|
||||
|
||||
let final_prefix = if let Some(instance) = instance {
|
||||
let const_name = syn::Ident::new(&format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site());
|
||||
let const_name = Ident::new(&format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site());
|
||||
quote!{ #instance::#const_name.as_bytes() }
|
||||
} else {
|
||||
quote!{ #prefix.as_bytes() }
|
||||
};
|
||||
|
||||
// generator for value
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>
|
||||
(#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>);
|
||||
let (struct_trait, impl_trait, trait_and_instance) = if ext::type_contains_ident(
|
||||
value_type, traitinstance
|
||||
) {
|
||||
(
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable),
|
||||
quote!(#traitinstance, #instance),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
quote!(#instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#instance #bound_instantiable),
|
||||
quote!(#instance)
|
||||
)
|
||||
};
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::StorageValue<#typ> for #name<#traitinstance, #instance>
|
||||
// generator for value
|
||||
quote! {
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#struct_trait>(
|
||||
#scrate::rstd::marker::PhantomData<(#trait_and_instance)>
|
||||
);
|
||||
|
||||
impl<#impl_trait> #scrate::storage::hashed::generator::StorageValue<#typ>
|
||||
for #name<#trait_and_instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
@@ -170,7 +188,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
};
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -184,14 +201,31 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
quote!{ #prefix.as_bytes() }
|
||||
};
|
||||
|
||||
let (struct_trait, impl_trait, trait_and_instance) = if ext::type_contains_ident(value_type, traitinstance)
|
||||
|| ext::type_contains_ident(kty, traitinstance)
|
||||
{
|
||||
(
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable),
|
||||
quote!(#traitinstance, #instance),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
quote!(#instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#instance #bound_instantiable),
|
||||
quote!(#instance)
|
||||
)
|
||||
};
|
||||
|
||||
// generator for map
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>
|
||||
(#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>);
|
||||
#visibility struct #name<#struct_trait>(
|
||||
#scrate::rstd::marker::PhantomData<(#trait_and_instance)>
|
||||
);
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance>
|
||||
impl<#impl_trait>
|
||||
#scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#trait_and_instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
@@ -235,8 +269,8 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ> for #name<#traitinstance, #instance>
|
||||
impl<#impl_trait> #scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ>
|
||||
for #name<#trait_and_instance>
|
||||
{}
|
||||
}
|
||||
}
|
||||
@@ -257,7 +291,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
} = self;
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -304,6 +337,26 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
};
|
||||
|
||||
let (struct_trait, impl_trait, trait_and_instance, trait_lifetime) = if ext::type_contains_ident(
|
||||
value_type,
|
||||
traitinstance
|
||||
) || ext::type_contains_ident(kty, traitinstance)
|
||||
{
|
||||
(
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable),
|
||||
quote!(#traitinstance, #instance),
|
||||
quote!(#traitinstance: 'static),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
quote!(#instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#instance #bound_instantiable),
|
||||
quote!(#instance),
|
||||
quote!()
|
||||
)
|
||||
};
|
||||
|
||||
// generator for linked map
|
||||
let helpers = quote! {
|
||||
/// Linkage data of an element (it's successor and predecessor)
|
||||
@@ -337,15 +390,14 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
pub _data: #phantom_data<V>,
|
||||
}
|
||||
|
||||
impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #traitinstance: #traittype, #instance #bound_instantiable>
|
||||
Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)>
|
||||
where #traitinstance: 'a
|
||||
impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #impl_trait>
|
||||
Iterator for Enumerator<'a, S, #kty, (#typ, #trait_and_instance)>
|
||||
{
|
||||
type Item = (#kty, #typ);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let next = self.next.take()?;
|
||||
let key_for = <super::#name<#traitinstance, #instance>
|
||||
let key_for = <super::#name<#trait_and_instance>
|
||||
as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>>::key_for(&next);
|
||||
|
||||
let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for)
|
||||
@@ -355,7 +407,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait Utils<#traitinstance: #traittype, #instance #bound_instantiable> {
|
||||
pub(crate) trait Utils<#struct_trait> {
|
||||
/// Update linkage when this element is removed.
|
||||
///
|
||||
/// Takes care of updating previous and next elements points
|
||||
@@ -388,9 +440,9 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
|
||||
let structure = quote! {
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#phantom_data<(#traitinstance #comma_instance)>);
|
||||
#visibility struct #name<#struct_trait>(#phantom_data<(#trait_and_instance)>);
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable> self::#inner_module::Utils<#traitinstance, #instance> for #name<#traitinstance, #instance> {
|
||||
impl<#impl_trait> self::#inner_module::Utils<#trait_and_instance> for #name<#trait_and_instance> {
|
||||
fn remove_linkage<S: #scrate::HashedStorage<#scrate::#hasher>>(
|
||||
linkage: self::#inner_module::Linkage<#kty>,
|
||||
storage: &mut S,
|
||||
@@ -477,8 +529,8 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
|
||||
#structure
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance>
|
||||
impl<#impl_trait>
|
||||
#scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#trait_and_instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
@@ -553,8 +605,10 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance>
|
||||
impl<#impl_trait>
|
||||
#scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> for #name<#trait_and_instance>
|
||||
where
|
||||
#trait_lifetime
|
||||
{
|
||||
fn head<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S) -> Option<#kty> {
|
||||
use self::#inner_module::Utils;
|
||||
@@ -562,18 +616,20 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
Self::read_head(storage)
|
||||
}
|
||||
|
||||
fn enumerate<'a, S>(storage: &'a S) -> #scrate::rstd::boxed::Box<dyn Iterator<Item = (#kty, #typ)> + 'a>
|
||||
where
|
||||
S: #scrate::HashedStorage<#scrate::#hasher>,
|
||||
#kty: 'a,
|
||||
#typ: 'a,
|
||||
fn enumerate<'a, S>(
|
||||
storage: &'a S
|
||||
) -> #scrate::rstd::boxed::Box<dyn Iterator<Item = (#kty, #typ)> + 'a>
|
||||
where
|
||||
S: #scrate::HashedStorage<#scrate::#hasher>,
|
||||
#kty: 'a,
|
||||
#typ: 'a,
|
||||
{
|
||||
use self::#inner_module::{Utils, Enumerator};
|
||||
|
||||
#scrate::rstd::boxed::Box::new(Enumerator {
|
||||
next: Self::read_head(storage),
|
||||
storage,
|
||||
_data: #phantom_data::<(#typ, #traitinstance, #instance)>::default(),
|
||||
_data: #phantom_data::<(#typ, #trait_and_instance)>::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -620,7 +676,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
};
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -634,14 +689,31 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
quote!{ #prefix.as_bytes() }
|
||||
};
|
||||
|
||||
let (struct_trait, impl_trait, trait_and_instance) = if ext::type_contains_ident(value_type, traitinstance)
|
||||
|| ext::type_contains_ident(k1ty, traitinstance)
|
||||
|| ext::type_contains_ident(k2ty, traitinstance)
|
||||
{
|
||||
(
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#traitinstance: #traittype, #instance #bound_instantiable),
|
||||
quote!(#traitinstance, #instance),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
quote!(#instance #bound_instantiable #equal_default_instance),
|
||||
quote!(#instance #bound_instantiable),
|
||||
quote!(#instance)
|
||||
)
|
||||
};
|
||||
|
||||
// generator for double map
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>
|
||||
(#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>);
|
||||
#visibility struct #name<#struct_trait>
|
||||
(#scrate::rstd::marker::PhantomData<(#trait_and_instance)>);
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#traitinstance, #instance>
|
||||
impl<#impl_trait>
|
||||
#scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#trait_and_instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
@@ -686,9 +758,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
#mutate_impl ;
|
||||
ret
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user