mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
pallet macro: allow to declare individual unbounded storage for those who cannot go into PoV (#9670)
* allow unbounded individual storage * better doc * fix UI tests * update doc * Update frame/support/procedural/src/pallet/parse/storage.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d565382b50
commit
1ebcbe1c34
@@ -98,28 +98,39 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
)
|
||||
};
|
||||
|
||||
// Depending on the flag `generate_storage_info` we use partial or full storage info from
|
||||
// storage.
|
||||
let (storage_info_span, storage_info_trait, storage_info_method) =
|
||||
if let Some(span) = def.pallet_struct.generate_storage_info {
|
||||
(
|
||||
span,
|
||||
quote::quote_spanned!(span => StorageInfoTrait),
|
||||
quote::quote_spanned!(span => storage_info),
|
||||
)
|
||||
} else {
|
||||
let span = def.pallet_struct.attr_span;
|
||||
(
|
||||
span,
|
||||
quote::quote_spanned!(span => PartialStorageInfoTrait),
|
||||
quote::quote_spanned!(span => partial_storage_info),
|
||||
)
|
||||
};
|
||||
let storage_info_span =
|
||||
def.pallet_struct.generate_storage_info.unwrap_or(def.pallet_struct.attr_span);
|
||||
|
||||
let storage_names = &def.storages.iter().map(|storage| &storage.ident).collect::<Vec<_>>();
|
||||
let storage_cfg_attrs =
|
||||
&def.storages.iter().map(|storage| &storage.cfg_attrs).collect::<Vec<_>>();
|
||||
|
||||
// Depending on the flag `generate_storage_info` and the storage attribute `unbounded`, we use
|
||||
// partial or full storage info from storage.
|
||||
let storage_info_traits = &def
|
||||
.storages
|
||||
.iter()
|
||||
.map(|storage| {
|
||||
if storage.unbounded || def.pallet_struct.generate_storage_info.is_none() {
|
||||
quote::quote_spanned!(storage_info_span => PartialStorageInfoTrait)
|
||||
} else {
|
||||
quote::quote_spanned!(storage_info_span => StorageInfoTrait)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let storage_info_methods = &def
|
||||
.storages
|
||||
.iter()
|
||||
.map(|storage| {
|
||||
if storage.unbounded || def.pallet_struct.generate_storage_info.is_none() {
|
||||
quote::quote_spanned!(storage_info_span => partial_storage_info)
|
||||
} else {
|
||||
quote::quote_spanned!(storage_info_span => storage_info)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let storage_info = quote::quote_spanned!(storage_info_span =>
|
||||
impl<#type_impl_gen> #frame_support::traits::StorageInfoTrait
|
||||
for #pallet_ident<#type_use_gen>
|
||||
@@ -136,8 +147,8 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
{
|
||||
let mut storage_info = <
|
||||
#storage_names<#type_use_gen>
|
||||
as #frame_support::traits::#storage_info_trait
|
||||
>::#storage_info_method();
|
||||
as #frame_support::traits::#storage_info_traits
|
||||
>::#storage_info_methods();
|
||||
res.append(&mut storage_info);
|
||||
}
|
||||
)*
|
||||
|
||||
@@ -27,6 +27,7 @@ mod keyword {
|
||||
syn::custom_keyword!(pallet);
|
||||
syn::custom_keyword!(getter);
|
||||
syn::custom_keyword!(storage_prefix);
|
||||
syn::custom_keyword!(unbounded);
|
||||
syn::custom_keyword!(OptionQuery);
|
||||
syn::custom_keyword!(ValueQuery);
|
||||
}
|
||||
@@ -34,15 +35,17 @@ mod keyword {
|
||||
/// Parse for one of the following:
|
||||
/// * `#[pallet::getter(fn dummy)]`
|
||||
/// * `#[pallet::storage_prefix = "CustomName"]`
|
||||
/// * `#[pallet::unbounded]`
|
||||
pub enum PalletStorageAttr {
|
||||
Getter(syn::Ident, proc_macro2::Span),
|
||||
StorageName(syn::LitStr, proc_macro2::Span),
|
||||
Unbounded(proc_macro2::Span),
|
||||
}
|
||||
|
||||
impl PalletStorageAttr {
|
||||
fn attr_span(&self) -> proc_macro2::Span {
|
||||
match self {
|
||||
Self::Getter(_, span) | Self::StorageName(_, span) => *span,
|
||||
Self::Getter(_, span) | Self::StorageName(_, span) | Self::Unbounded(span) => *span,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,12 +79,45 @@ impl syn::parse::Parse for PalletStorageAttr {
|
||||
})?;
|
||||
|
||||
Ok(Self::StorageName(renamed_prefix, attr_span))
|
||||
} else if lookahead.peek(keyword::unbounded) {
|
||||
content.parse::<keyword::unbounded>()?;
|
||||
|
||||
Ok(Self::Unbounded(attr_span))
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PalletStorageAttrInfo {
|
||||
getter: Option<syn::Ident>,
|
||||
rename_as: Option<syn::LitStr>,
|
||||
unbounded: bool,
|
||||
}
|
||||
|
||||
impl PalletStorageAttrInfo {
|
||||
fn from_attrs(attrs: Vec<PalletStorageAttr>) -> syn::Result<Self> {
|
||||
let mut getter = None;
|
||||
let mut rename_as = None;
|
||||
let mut unbounded = false;
|
||||
for attr in attrs {
|
||||
match attr {
|
||||
PalletStorageAttr::Getter(ident, ..) if getter.is_none() => getter = Some(ident),
|
||||
PalletStorageAttr::StorageName(name, ..) if rename_as.is_none() =>
|
||||
rename_as = Some(name),
|
||||
PalletStorageAttr::Unbounded(..) if !unbounded => unbounded = true,
|
||||
attr =>
|
||||
return Err(syn::Error::new(
|
||||
attr.attr_span(),
|
||||
"Invalid attribute: Duplicate attribute",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(PalletStorageAttrInfo { getter, rename_as, unbounded })
|
||||
}
|
||||
}
|
||||
|
||||
/// The value and key types used by storages. Needed to expand metadata.
|
||||
pub enum Metadata {
|
||||
Value { value: syn::Type },
|
||||
@@ -131,6 +167,8 @@ pub struct StorageDef {
|
||||
/// generics of the storage.
|
||||
/// If generics are not named, this is none.
|
||||
pub named_generics: Option<StorageGenerics>,
|
||||
/// If the value stored in this storage is unbounded.
|
||||
pub unbounded: bool,
|
||||
}
|
||||
|
||||
/// The parsed generic from the
|
||||
@@ -629,25 +667,8 @@ impl StorageDef {
|
||||
};
|
||||
|
||||
let attrs: Vec<PalletStorageAttr> = helper::take_item_pallet_attrs(&mut item.attrs)?;
|
||||
let (mut getters, mut names) = attrs
|
||||
.into_iter()
|
||||
.partition::<Vec<_>, _>(|attr| matches!(attr, PalletStorageAttr::Getter(..)));
|
||||
if getters.len() > 1 {
|
||||
let msg = "Invalid pallet::storage, multiple argument pallet::getter found";
|
||||
return Err(syn::Error::new(getters[1].attr_span(), msg))
|
||||
}
|
||||
if names.len() > 1 {
|
||||
let msg = "Invalid pallet::storage, multiple argument pallet::storage_prefix found";
|
||||
return Err(syn::Error::new(names[1].attr_span(), msg))
|
||||
}
|
||||
let getter = getters.pop().map(|attr| match attr {
|
||||
PalletStorageAttr::Getter(ident, _) => ident,
|
||||
_ => unreachable!(),
|
||||
});
|
||||
let rename_as = names.pop().map(|attr| match attr {
|
||||
PalletStorageAttr::StorageName(lit, _) => lit,
|
||||
_ => unreachable!(),
|
||||
});
|
||||
let PalletStorageAttrInfo { getter, rename_as, unbounded } =
|
||||
PalletStorageAttrInfo::from_attrs(attrs)?;
|
||||
|
||||
let cfg_attrs = helper::get_item_cfg_attrs(&item.attrs);
|
||||
|
||||
@@ -704,6 +725,7 @@ impl StorageDef {
|
||||
where_clause,
|
||||
cfg_attrs,
|
||||
named_generics,
|
||||
unbounded,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user