Implement ResultQuery (#11257)

* Implement ResultQuery

* Fix test expectations

* Add more tests

* Fix test expectations

* Clean up some names

* Silence warnings

* Specify error type when supplying error type to ResultQuery

* cargo fmt

* Add support for type parameters in parameter_types macro

* Reduce deeply indented code

* Fixes

* Update test expectation

* Rewrite and document formula for calculating max storage size

* More docs

* cargo fmt

* formatting

Co-authored-by: parity-processbot <>
This commit is contained in:
Keith Yeung
2022-08-25 01:47:08 +08:00
committed by GitHub
parent 6aba2fdc99
commit edc8f7b409
16 changed files with 770 additions and 77 deletions
+52 -29
View File
@@ -281,79 +281,85 @@ pub use frame_support_procedural::storage_alias;
macro_rules! parameter_types {
(
$( #[ $attr:meta ] )*
$vis:vis const $name:ident: $type:ty = $value:expr;
$vis:vis const $name:ident $(< $($ty_params:ident),* >)?: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
$vis struct $name;
$crate::parameter_types!(IMPL_CONST $name , $type , $value);
$vis struct $name $(
< $($ty_params),* >( $($crate::sp_std::marker::PhantomData<$ty_params>),* )
)?;
$crate::parameter_types!(IMPL_CONST $name , $type , $value $( $(, $ty_params)* )?);
$crate::parameter_types!( $( $rest )* );
);
(
$( #[ $attr:meta ] )*
$vis:vis $name:ident: $type:ty = $value:expr;
$vis:vis $name:ident $(< $($ty_params:ident),* >)?: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
$vis struct $name;
$crate::parameter_types!(IMPL $name, $type, $value);
$vis struct $name $(
< $($ty_params),* >( $($crate::sp_std::marker::PhantomData<$ty_params>),* )
)?;
$crate::parameter_types!(IMPL $name, $type, $value $( $(, $ty_params)* )?);
$crate::parameter_types!( $( $rest )* );
);
(
$( #[ $attr:meta ] )*
$vis:vis storage $name:ident: $type:ty = $value:expr;
$vis:vis storage $name:ident $(< $($ty_params:ident),* >)?: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
$vis struct $name;
$crate::parameter_types!(IMPL_STORAGE $name, $type, $value);
$vis struct $name $(
< $($ty_params),* >( $($crate::sp_std::marker::PhantomData<$ty_params>),* )
)?;
$crate::parameter_types!(IMPL_STORAGE $name, $type, $value $( $(, $ty_params)* )?);
$crate::parameter_types!( $( $rest )* );
);
() => ();
(IMPL_CONST $name:ident, $type:ty, $value:expr) => {
impl $name {
(IMPL_CONST $name:ident, $type:ty, $value:expr $(, $ty_params:ident)*) => {
impl< $($ty_params),* > $name< $($ty_params),* > {
/// Returns the value of this parameter type.
pub const fn get() -> $type {
$value
}
}
impl<I: From<$type>> $crate::traits::Get<I> for $name {
fn get() -> I {
I::from(Self::get())
impl<_I: From<$type> $(, $ty_params)*> $crate::traits::Get<_I> for $name< $($ty_params),* > {
fn get() -> _I {
_I::from(Self::get())
}
}
impl $crate::traits::TypedGet for $name {
impl< $($ty_params),* > $crate::traits::TypedGet for $name< $($ty_params),* > {
type Type = $type;
fn get() -> $type {
Self::get()
}
}
};
(IMPL $name:ident, $type:ty, $value:expr) => {
impl $name {
(IMPL $name:ident, $type:ty, $value:expr $(, $ty_params:ident)*) => {
impl< $($ty_params),* > $name< $($ty_params),* > {
/// Returns the value of this parameter type.
pub fn get() -> $type {
$value
}
}
impl<I: From<$type>> $crate::traits::Get<I> for $name {
fn get() -> I {
I::from(Self::get())
impl<_I: From<$type>, $(, $ty_params)*> $crate::traits::Get<_I> for $name< $($ty_params),* > {
fn get() -> _I {
_I::from(Self::get())
}
}
impl $crate::traits::TypedGet for $name {
impl< $($ty_params),* > $crate::traits::TypedGet for $name< $($ty_params),* > {
type Type = $type;
fn get() -> $type {
Self::get()
}
}
};
(IMPL_STORAGE $name:ident, $type:ty, $value:expr) => {
impl $name {
(IMPL_STORAGE $name:ident, $type:ty, $value:expr $(, $ty_params:ident)*) => {
impl< $($ty_params),* > $name< $($ty_params),* > {
/// Returns the key for this parameter type.
#[allow(unused)]
pub fn key() -> [u8; 16] {
@@ -379,13 +385,13 @@ macro_rules! parameter_types {
}
}
impl<I: From<$type>> $crate::traits::Get<I> for $name {
fn get() -> I {
I::from(Self::get())
impl<_I: From<$type> $(, $ty_params)*> $crate::traits::Get<_I> for $name< $($ty_params),* > {
fn get() -> _I {
_I::from(Self::get())
}
}
impl $crate::traits::TypedGet for $name {
impl< $($ty_params),* > $crate::traits::TypedGet for $name< $($ty_params),* > {
type Type = $type;
fn get() -> $type {
Self::get()
@@ -1360,8 +1366,8 @@ pub mod pallet_prelude {
storage::{
bounded_vec::BoundedVec,
types::{
CountedStorageMap, Key as NMapKey, OptionQuery, StorageDoubleMap, StorageMap,
StorageNMap, StorageValue, ValueQuery,
CountedStorageMap, Key as NMapKey, OptionQuery, ResultQuery, StorageDoubleMap,
StorageMap, StorageNMap, StorageValue, ValueQuery,
},
},
traits::{
@@ -1835,6 +1841,23 @@ pub mod pallet_prelude {
/// All the `cfg` attributes are automatically copied to the items generated for the storage,
/// i.e. the getter, storage prefix, and the metadata element etc.
///
/// Any type placed as the `QueryKind` parameter must implement
/// [`frame_support::storage::types::QueryKindTrait`]. There are 3 implementations of this
/// trait by default:
/// 1. [`frame_support::storage::types::OptionQuery`], the default `QueryKind` used when this
/// type parameter is omitted. Specifying this as the `QueryKind` would cause storage map
/// APIs that return a `QueryKind` to instead return an `Option`, returning `Some` when a
/// value does exist under a specified storage key, and `None` otherwise.
/// 2. [`frame_support::storage::types::ValueQuery`] causes storage map APIs that return a
/// `QueryKind` to instead return the value type. In cases where a value does not exist
/// under a specified storage key, the `OnEmpty` type parameter on `QueryKindTrait` is used
/// to return an appropriate value.
/// 3. [`frame_support::storage::types::ResultQuery`] causes storage map APIs that return a
/// `QueryKind` to instead return a `Result<T, E>`, with `T` being the value type and `E`
/// being the pallet error type specified by the `#[pallet::error]` attribute. In cases
/// where a value does not exist under a specified storage key, an `Err` with the specified
/// pallet error variant is returned.
///
/// NOTE: If the `QueryKind` generic parameter is still generic at this stage or is using some
/// type alias then the generation of the getter might fail. In this case the getter can be
/// implemented manually.