mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-22 10:21:04 +00:00
Allow to name the generic for storages in #[pallet::storage] (#8751)
* implement named generic for storages * fix error message on unexpected name for generic
This commit is contained in:
committed by
GitHub
parent
ed39290f91
commit
0b30049417
@@ -16,7 +16,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::pallet::Def;
|
||||
use crate::pallet::parse::storage::{Metadata, QueryKind};
|
||||
use crate::pallet::parse::storage::{Metadata, QueryKind, StorageGenerics};
|
||||
use frame_support_procedural_tools::clean_type_string;
|
||||
|
||||
/// Generate the prefix_ident related the the storage.
|
||||
@@ -25,50 +25,112 @@ fn prefix_ident(storage_ident: &syn::Ident) -> syn::Ident {
|
||||
syn::Ident::new(&format!("_GeneratedPrefixForStorage{}", storage_ident), storage_ident.span())
|
||||
}
|
||||
|
||||
/// * generate StoragePrefix structs (e.g. for a storage `MyStorage` a struct with the name
|
||||
/// `_GeneratedPrefixForStorage$NameOfStorage` is generated) and implements StorageInstance trait.
|
||||
/// * replace the first generic `_` by the generated prefix structure
|
||||
/// * generate metadatas
|
||||
pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
/// * if generics are unnamed: replace the first generic `_` by the generated prefix structure
|
||||
/// * if generics are named: reorder the generic, remove their name, and add the missing ones.
|
||||
/// * Add `#[allow(type_alias_bounds)]`
|
||||
pub fn process_generics(def: &mut Def) {
|
||||
let frame_support = &def.frame_support;
|
||||
let frame_system = &def.frame_system;
|
||||
let pallet_ident = &def.pallet_struct.pallet;
|
||||
|
||||
// Replace first arg `_` by the generated prefix structure.
|
||||
// Add `#[allow(type_alias_bounds)]`
|
||||
for storage_def in def.storages.iter_mut() {
|
||||
let item = &mut def.item.content.as_mut().expect("Checked by def").1[storage_def.index];
|
||||
|
||||
let typ_item = if let syn::Item::Type(t) = item {
|
||||
t
|
||||
} else {
|
||||
unreachable!("Checked by def");
|
||||
let typ_item = match item {
|
||||
syn::Item::Type(t) => t,
|
||||
_ => unreachable!("Checked by def"),
|
||||
};
|
||||
|
||||
typ_item.attrs.push(syn::parse_quote!(#[allow(type_alias_bounds)]));
|
||||
|
||||
let typ_path = if let syn::Type::Path(p) = &mut *typ_item.ty {
|
||||
p
|
||||
} else {
|
||||
unreachable!("Checked by def");
|
||||
let typ_path = match &mut *typ_item.ty {
|
||||
syn::Type::Path(p) => p,
|
||||
_ => unreachable!("Checked by def"),
|
||||
};
|
||||
|
||||
let args = if let syn::PathArguments::AngleBracketed(args) =
|
||||
&mut typ_path.path.segments[0].arguments
|
||||
{
|
||||
args
|
||||
} else {
|
||||
unreachable!("Checked by def");
|
||||
let args = match &mut typ_path.path.segments[0].arguments {
|
||||
syn::PathArguments::AngleBracketed(args) => args,
|
||||
_ => unreachable!("Checked by def"),
|
||||
};
|
||||
|
||||
let prefix_ident = prefix_ident(&storage_def.ident);
|
||||
let type_use_gen = if def.config.has_instance {
|
||||
quote::quote_spanned!(storage_def.attr_span => T, I)
|
||||
} else {
|
||||
quote::quote_spanned!(storage_def.attr_span => T)
|
||||
};
|
||||
let prefix_ident = prefix_ident(&storage_def.ident);
|
||||
args.args[0] = syn::parse_quote!( #prefix_ident<#type_use_gen> );
|
||||
|
||||
let default_query_kind: syn::Type =
|
||||
syn::parse_quote!(#frame_support::storage::types::OptionQuery);
|
||||
let default_on_empty: syn::Type =
|
||||
syn::parse_quote!(#frame_support::traits::GetDefault);
|
||||
let default_max_values: syn::Type =
|
||||
syn::parse_quote!(#frame_support::traits::GetDefault);
|
||||
|
||||
if let Some(named_generics) = storage_def.named_generics.clone() {
|
||||
args.args.clear();
|
||||
args.args.push(syn::parse_quote!( #prefix_ident<#type_use_gen> ));
|
||||
match named_generics {
|
||||
StorageGenerics::Value { value, query_kind, on_empty } => {
|
||||
args.args.push(syn::GenericArgument::Type(value));
|
||||
let query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
|
||||
args.args.push(syn::GenericArgument::Type(query_kind));
|
||||
let on_empty = on_empty.unwrap_or_else(|| default_on_empty.clone());
|
||||
args.args.push(syn::GenericArgument::Type(on_empty));
|
||||
}
|
||||
StorageGenerics::Map { hasher, key, value, query_kind, on_empty, max_values } => {
|
||||
args.args.push(syn::GenericArgument::Type(hasher));
|
||||
args.args.push(syn::GenericArgument::Type(key));
|
||||
args.args.push(syn::GenericArgument::Type(value));
|
||||
let query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
|
||||
args.args.push(syn::GenericArgument::Type(query_kind));
|
||||
let on_empty = on_empty.unwrap_or_else(|| default_on_empty.clone());
|
||||
args.args.push(syn::GenericArgument::Type(on_empty));
|
||||
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
|
||||
args.args.push(syn::GenericArgument::Type(max_values));
|
||||
}
|
||||
StorageGenerics::DoubleMap {
|
||||
hasher1, key1, hasher2, key2, value, query_kind, on_empty, max_values,
|
||||
} => {
|
||||
args.args.push(syn::GenericArgument::Type(hasher1));
|
||||
args.args.push(syn::GenericArgument::Type(key1));
|
||||
args.args.push(syn::GenericArgument::Type(hasher2));
|
||||
args.args.push(syn::GenericArgument::Type(key2));
|
||||
args.args.push(syn::GenericArgument::Type(value));
|
||||
let query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
|
||||
args.args.push(syn::GenericArgument::Type(query_kind));
|
||||
let on_empty = on_empty.unwrap_or_else(|| default_on_empty.clone());
|
||||
args.args.push(syn::GenericArgument::Type(on_empty));
|
||||
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
|
||||
args.args.push(syn::GenericArgument::Type(max_values));
|
||||
}
|
||||
StorageGenerics::NMap { keygen, value, query_kind, on_empty, max_values, } => {
|
||||
args.args.push(syn::GenericArgument::Type(keygen));
|
||||
args.args.push(syn::GenericArgument::Type(value));
|
||||
let query_kind = query_kind.unwrap_or_else(|| default_query_kind.clone());
|
||||
args.args.push(syn::GenericArgument::Type(query_kind));
|
||||
let on_empty = on_empty.unwrap_or_else(|| default_on_empty.clone());
|
||||
args.args.push(syn::GenericArgument::Type(on_empty));
|
||||
let max_values = max_values.unwrap_or_else(|| default_max_values.clone());
|
||||
args.args.push(syn::GenericArgument::Type(max_values));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
args.args[0] = syn::parse_quote!( #prefix_ident<#type_use_gen> );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// * generate StoragePrefix structs (e.g. for a storage `MyStorage` a struct with the name
|
||||
/// `_GeneratedPrefixForStorage$NameOfStorage` is generated) and implements StorageInstance trait.
|
||||
/// * if generics are unnamed: replace the first generic `_` by the generated prefix structure
|
||||
/// * if generics are named: reorder the generic, remove their name, and add the missing ones.
|
||||
/// * Add `#[allow(type_alias_bounds)]` on storages type alias
|
||||
/// * generate metadatas
|
||||
pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
process_generics(def);
|
||||
|
||||
let frame_support = &def.frame_support;
|
||||
let frame_system = &def.frame_system;
|
||||
let pallet_ident = &def.pallet_struct.pallet;
|
||||
|
||||
|
||||
let entries = def.storages.iter()
|
||||
.map(|storage| {
|
||||
|
||||
Reference in New Issue
Block a user