mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 13:48:00 +00:00
[Feature] Introduce storage_alias for CountedStorageMap (#13366)
* [Feature] Introduce storagage_alias for CountedStorageMap * bit more dry * bit more dry * address review comments * some tests and fixes * fix ui tests * Apply suggestions from code review Co-authored-by: Bastian Köcher <git@kchr.de> * compare metadata --------- Co-authored-by: parity-processbot <> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -69,6 +69,12 @@ fn get_cargo_env_var<T: FromStr>(version_env: &str) -> std::result::Result<T, ()
|
||||
T::from_str(&version).map_err(drop)
|
||||
}
|
||||
|
||||
/// Generate the counter_prefix related to the storage.
|
||||
/// counter_prefix is used by counted storage map.
|
||||
fn counter_prefix(prefix: &str) -> String {
|
||||
format!("CounterFor{}", prefix)
|
||||
}
|
||||
|
||||
/// Declares strongly-typed wrappers around codec-compatible types in storage.
|
||||
///
|
||||
/// ## Example
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::pallet::{
|
||||
parse::storage::{Metadata, QueryKind, StorageDef, StorageGenerics},
|
||||
Def,
|
||||
use crate::{
|
||||
counter_prefix,
|
||||
pallet::{
|
||||
parse::storage::{Metadata, QueryKind, StorageDef, StorageGenerics},
|
||||
Def,
|
||||
},
|
||||
};
|
||||
use quote::ToTokens;
|
||||
use std::{collections::HashMap, ops::IndexMut};
|
||||
@@ -39,12 +42,6 @@ fn counter_prefix_ident(storage_ident: &syn::Ident) -> syn::Ident {
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate the counter_prefix related to the storage.
|
||||
/// counter_prefix is used by counted storage map.
|
||||
fn counter_prefix(prefix: &str) -> String {
|
||||
format!("CounterFor{}", prefix)
|
||||
}
|
||||
|
||||
/// Check for duplicated storage prefixes. This step is necessary since users can specify an
|
||||
/// alternative storage prefix using the #[pallet::storage_prefix] syntax, and we need to ensure
|
||||
/// that the prefix specified by the user is not a duplicate of an existing one.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
//! Implementation of the `storage_alias` attribute macro.
|
||||
|
||||
use crate::counter_prefix;
|
||||
use frame_support_procedural_tools::generate_crate_access_2018;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
@@ -136,6 +137,7 @@ impl ToTokens for SimpleGenerics {
|
||||
mod storage_types {
|
||||
syn::custom_keyword!(StorageValue);
|
||||
syn::custom_keyword!(StorageMap);
|
||||
syn::custom_keyword!(CountedStorageMap);
|
||||
syn::custom_keyword!(StorageDoubleMap);
|
||||
syn::custom_keyword!(StorageNMap);
|
||||
}
|
||||
@@ -168,6 +170,21 @@ enum StorageType {
|
||||
_trailing_comma: Option<Token![,]>,
|
||||
_gt_token: Token![>],
|
||||
},
|
||||
CountedMap {
|
||||
_kw: storage_types::CountedStorageMap,
|
||||
_lt_token: Token![<],
|
||||
prefix: SimplePath,
|
||||
prefix_generics: Option<TypeGenerics>,
|
||||
_hasher_comma: Token![,],
|
||||
hasher_ty: Type,
|
||||
_key_comma: Token![,],
|
||||
key_ty: Type,
|
||||
_value_comma: Token![,],
|
||||
value_ty: Type,
|
||||
query_type: Option<(Token![,], Type)>,
|
||||
_trailing_comma: Option<Token![,]>,
|
||||
_gt_token: Token![>],
|
||||
},
|
||||
DoubleMap {
|
||||
_kw: storage_types::StorageDoubleMap,
|
||||
_lt_token: Token![<],
|
||||
@@ -235,12 +252,22 @@ impl StorageType {
|
||||
>;
|
||||
}
|
||||
},
|
||||
Self::CountedMap {
|
||||
value_ty, query_type, hasher_ty, key_ty, prefix_generics, ..
|
||||
} |
|
||||
Self::Map { value_ty, query_type, hasher_ty, key_ty, prefix_generics, .. } => {
|
||||
let query_type = query_type.as_ref().map(|(c, t)| quote!(#c #t));
|
||||
let map_type = Ident::new(
|
||||
match self {
|
||||
Self::Map { .. } => "StorageMap",
|
||||
_ => "CountedStorageMap",
|
||||
},
|
||||
Span::call_site(),
|
||||
);
|
||||
|
||||
quote! {
|
||||
#( #attributes )*
|
||||
#visibility type #storage_name #storage_generics = #crate_::storage::types::StorageMap<
|
||||
#visibility type #storage_name #storage_generics = #crate_::storage::types::#map_type<
|
||||
#storage_instance #prefix_generics,
|
||||
#hasher_ty,
|
||||
#key_ty,
|
||||
@@ -296,6 +323,7 @@ impl StorageType {
|
||||
match self {
|
||||
Self::Value { prefix, .. } |
|
||||
Self::Map { prefix, .. } |
|
||||
Self::CountedMap { prefix, .. } |
|
||||
Self::NMap { prefix, .. } |
|
||||
Self::DoubleMap { prefix, .. } => prefix,
|
||||
}
|
||||
@@ -306,6 +334,7 @@ impl StorageType {
|
||||
match self {
|
||||
Self::Value { prefix_generics, .. } |
|
||||
Self::Map { prefix_generics, .. } |
|
||||
Self::CountedMap { prefix_generics, .. } |
|
||||
Self::NMap { prefix_generics, .. } |
|
||||
Self::DoubleMap { prefix_generics, .. } => prefix_generics.as_ref(),
|
||||
}
|
||||
@@ -363,6 +392,22 @@ impl Parse for StorageType {
|
||||
_trailing_comma: input.peek(Token![,]).then(|| input.parse()).transpose()?,
|
||||
_gt_token: input.parse()?,
|
||||
})
|
||||
} else if lookahead.peek(storage_types::CountedStorageMap) {
|
||||
Ok(Self::CountedMap {
|
||||
_kw: input.parse()?,
|
||||
_lt_token: input.parse()?,
|
||||
prefix: input.parse()?,
|
||||
prefix_generics: parse_pallet_generics(input)?,
|
||||
_hasher_comma: input.parse()?,
|
||||
hasher_ty: input.parse()?,
|
||||
_key_comma: input.parse()?,
|
||||
key_ty: input.parse()?,
|
||||
_value_comma: input.parse()?,
|
||||
value_ty: input.parse()?,
|
||||
query_type: parse_query_type(input)?,
|
||||
_trailing_comma: input.peek(Token![,]).then(|| input.parse()).transpose()?,
|
||||
_gt_token: input.parse()?,
|
||||
})
|
||||
} else if lookahead.peek(storage_types::StorageDoubleMap) {
|
||||
Ok(Self::DoubleMap {
|
||||
_kw: input.parse()?,
|
||||
@@ -476,6 +521,7 @@ pub fn storage_alias(input: TokenStream) -> Result<TokenStream> {
|
||||
input.storage_type.prefix(),
|
||||
input.storage_type.prefix_generics(),
|
||||
&input.visibility,
|
||||
matches!(input.storage_type, StorageType::CountedMap { .. }),
|
||||
)?;
|
||||
|
||||
let definition = input.storage_type.generate_type_declaration(
|
||||
@@ -511,6 +557,7 @@ fn generate_storage_instance(
|
||||
prefix: &SimplePath,
|
||||
prefix_generics: Option<&TypeGenerics>,
|
||||
visibility: &Visibility,
|
||||
is_counted_map: bool,
|
||||
) -> Result<StorageInstance> {
|
||||
if let Some(ident) = prefix.get_ident().filter(|i| *i == "_") {
|
||||
return Err(Error::new(ident.span(), "`_` is not allowed as prefix by `storage_alias`."))
|
||||
@@ -546,9 +593,37 @@ fn generate_storage_instance(
|
||||
|
||||
let where_clause = storage_where_clause.map(|w| quote!(#w)).unwrap_or_default();
|
||||
|
||||
let name = Ident::new(&format!("{}_Storage_Instance", storage_name), Span::call_site());
|
||||
let name_str = format!("{}_Storage_Instance", storage_name);
|
||||
let name = Ident::new(&name_str, Span::call_site());
|
||||
let storage_name_str = storage_name.to_string();
|
||||
|
||||
let counter_code = is_counted_map.then(|| {
|
||||
let counter_name = Ident::new(&counter_prefix(&name_str), Span::call_site());
|
||||
let counter_storage_name_str = counter_prefix(&storage_name_str);
|
||||
|
||||
quote! {
|
||||
#visibility struct #counter_name< #impl_generics >(
|
||||
#crate_::sp_std::marker::PhantomData<(#type_generics)>
|
||||
) #where_clause;
|
||||
|
||||
impl<#impl_generics> #crate_::traits::StorageInstance
|
||||
for #counter_name< #type_generics > #where_clause
|
||||
{
|
||||
fn pallet_prefix() -> &'static str {
|
||||
#pallet_prefix
|
||||
}
|
||||
|
||||
const STORAGE_PREFIX: &'static str = #counter_storage_name_str;
|
||||
}
|
||||
|
||||
impl<#impl_generics> #crate_::storage::types::CountedStorageMapInstance
|
||||
for #name< #type_generics > #where_clause
|
||||
{
|
||||
type CounterPrefix = #counter_name < #type_generics >;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Implement `StorageInstance` trait.
|
||||
let code = quote! {
|
||||
#visibility struct #name< #impl_generics >(
|
||||
@@ -564,6 +639,8 @@ fn generate_storage_instance(
|
||||
|
||||
const STORAGE_PREFIX: &'static str = #storage_name_str;
|
||||
}
|
||||
|
||||
#counter_code
|
||||
};
|
||||
|
||||
Ok(StorageInstance { name, code })
|
||||
|
||||
Reference in New Issue
Block a user