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:
Guillaume Thiolliere
2021-05-19 09:11:11 +02:00
committed by GitHub
parent ed39290f91
commit 0b30049417
18 changed files with 746 additions and 136 deletions
+35 -10
View File
@@ -1586,11 +1586,28 @@ pub mod pallet_prelude {
/// #[pallet::storage]
/// #[pallet::getter(fn $getter_name)] // optional
/// $vis type $StorageName<$some_generic> $optional_where_clause
/// = $StorageType<$generic_name = $some_generics, $other_name = $some_other, ...>;
/// ```
/// or with unnamed generic
/// ```ignore
/// #[pallet::storage]
/// #[pallet::getter(fn $getter_name)] // optional
/// $vis type $StorageName<$some_generic> $optional_where_clause
/// = $StorageType<_, $some_generics, ...>;
/// ```
/// I.e. it must be a type alias, with generics: `T` or `T: Config`, aliased type must be one
/// of `StorageValue`, `StorageMap` or `StorageDoubleMap` (defined in frame_support).
/// Their first generic must be `_` as it is written by the macro itself.
/// The generic arguments of the storage type can be given in two manner: named and unnamed.
/// For named generic argument: the name for each argument is the one as define on the storage
/// struct:
/// * [`pallet_prelude::StorageValue`] expect `Value` and optionally `QueryKind` and `OnEmpty`,
/// * [`pallet_prelude::StorageMap`] expect `Hasher`, `Key`, `Value` and optionally `QueryKind` and
/// `OnEmpty`,
/// * [`pallet_prelude::StorageDoubleMap`] expect `Hasher1`, `Key1`, `Hasher2`, `Key2`, `Value` and
/// optionally `QueryKind` and `OnEmpty`.
///
/// For unnamed generic argument: Their first generic must be `_` as it is replaced by the macro
/// and other generic must declared as a normal declaration of type generic in rust.
///
/// The Prefix generic written by the macro is generated using `PalletInfo::name::<Pallet<..>>()`
/// and the name of the storage type.
@@ -1604,6 +1621,12 @@ pub mod pallet_prelude {
/// ```ignore
/// #[pallet::storage]
/// #[pallet::getter(fn my_storage)]
/// pub(super) type MyStorage<T> = StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
/// ```
/// or
/// ```ignore
/// #[pallet::storage]
/// #[pallet::getter(fn my_storage)]
/// pub(super) type MyStorage<T> = StorageMap<_, Blake2_128Concat, u32, u32>;
/// ```
///
@@ -1613,7 +1636,7 @@ pub mod pallet_prelude {
/// ```ignore
/// #[cfg(feature = "my-feature")]
/// #[pallet::storage]
/// pub(super) type MyStorage<T> = StorageValue<_, u32>;
/// pub(super) type MyStorage<T> = StorageValue<Value = u32>;
/// ```
///
/// All the `cfg` attributes are automatically copied to the items generated for the storage, i.e. the
@@ -1630,10 +1653,11 @@ pub mod pallet_prelude {
/// ### Macro expansion
///
/// For each storage item the macro generates a struct named
/// `_GeneratedPrefixForStorage$NameOfStorage`, and implements [`StorageInstance`](traits::StorageInstance)
/// on it using the pallet and storage name. It then uses it as the first generic of the aliased
/// type.
/// `_GeneratedPrefixForStorage$NameOfStorage`, and implements
/// [`StorageInstance`](traits::StorageInstance) on it using the pallet and storage name. It then
/// uses it as the first generic of the aliased type.
///
/// For named generic, the macro will reorder the generics, and remove the names.
///
/// The macro implements the function `storage_metadata` on `Pallet` implementing the metadata for
/// all storage items based on their kind:
@@ -1915,12 +1939,13 @@ pub mod pallet_prelude {
/// // storage item. Thus generic hasher is supported.
/// #[pallet::storage]
/// pub(super) type MyStorageValue<T: Config> =
/// StorageValue<_, T::Balance, ValueQuery, MyDefault<T>>;
/// StorageValue<Value = T::Balance, QueryKind = ValueQuery, OnEmpty = MyDefault<T>>;
///
/// // Another storage declaration
/// #[pallet::storage]
/// #[pallet::getter(fn my_storage)]
/// pub(super) type MyStorage<T> = StorageMap<_, Blake2_128Concat, u32, u32>;
/// pub(super) type MyStorage<T> =
/// StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
///
/// // Declare the genesis config (optional).
/// //
@@ -2057,12 +2082,12 @@ pub mod pallet_prelude {
///
/// #[pallet::storage]
/// pub(super) type MyStorageValue<T: Config<I>, I: 'static = ()> =
/// StorageValue<_, T::Balance, ValueQuery, MyDefault<T, I>>;
/// StorageValue<Value = T::Balance, QueryKind = ValueQuery, OnEmpty = MyDefault<T, I>>;
///
/// #[pallet::storage]
/// #[pallet::getter(fn my_storage)]
/// pub(super) type MyStorage<T, I = ()> =
/// StorageMap<_, Blake2_128Concat, u32, u32>;
/// StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
///
/// #[pallet::genesis_config]
/// #[derive(Default)]
@@ -2234,7 +2259,7 @@ pub mod pallet_prelude {
/// ```ignore
/// #[pallet::type_value] fn MyStorageOnEmpty() -> u32 { 3u32 }
/// #[pallet::storage]
/// pub(super) type MyStorage<T> = StorageValue<u32, ValueQuery, MyStorageOnEmpty>;
/// pub(super) type MyStorage<T> = StorageValue<_, u32, ValueQuery, MyStorageOnEmpty>;
/// ```
///
/// NOTE: `decl_storage` also generates functions `assimilate_storage` and `build_storage`