mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 23:57:56 +00:00
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:
@@ -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.
|
||||
|
||||
@@ -42,9 +42,11 @@ pub use value::StorageValue;
|
||||
/// Trait implementing how the storage optional value is converted into the queried type.
|
||||
///
|
||||
/// It is implemented by:
|
||||
/// * `OptionQuery` which convert an optional value to an optional value, user when querying storage
|
||||
/// will get an optional value.
|
||||
/// * `ValueQuery` which convert an optional value to a value, user when querying storage will get a
|
||||
/// * `OptionQuery` which converts an optional value to an optional value, used when querying
|
||||
/// storage returns an optional value.
|
||||
/// * `ResultQuery` which converts an optional value to a result value, used when querying storage
|
||||
/// returns a result value.
|
||||
/// * `ValueQuery` which converts an optional value to a value, used when querying storage returns a
|
||||
/// value.
|
||||
pub trait QueryKindTrait<Value, OnEmpty> {
|
||||
/// Metadata for the storage kind.
|
||||
@@ -85,6 +87,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement QueryKindTrait with query being `Result<Value, PalletError>`
|
||||
pub struct ResultQuery<Error>(sp_std::marker::PhantomData<Error>);
|
||||
impl<Value, Error, OnEmpty> QueryKindTrait<Value, OnEmpty> for ResultQuery<Error>
|
||||
where
|
||||
Value: FullCodec + 'static,
|
||||
Error: FullCodec + 'static,
|
||||
OnEmpty: crate::traits::Get<Result<Value, Error>>,
|
||||
{
|
||||
const METADATA: StorageEntryModifier = StorageEntryModifier::Optional;
|
||||
|
||||
type Query = Result<Value, Error>;
|
||||
|
||||
fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
|
||||
match v {
|
||||
Some(v) => Ok(v),
|
||||
None => OnEmpty::get(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
|
||||
v.ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement QueryKindTrait with query being `Value`
|
||||
pub struct ValueQuery;
|
||||
impl<Value, OnEmpty> QueryKindTrait<Value, OnEmpty> for ValueQuery
|
||||
|
||||
Reference in New Issue
Block a user