1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Storage types to build abstraction on storage, they implements storage traits such as
//! StorageMap and others.
use codec::FullCodec;
use sp_metadata_ir::{StorageEntryMetadataIR, StorageEntryModifierIR};
use sp_std::prelude::*;
mod counted_map;
mod counted_nmap;
mod double_map;
mod key;
mod map;
mod nmap;
mod value;
pub use counted_map::{CountedStorageMap, CountedStorageMapInstance};
pub use counted_nmap::{CountedStorageNMap, CountedStorageNMapInstance};
pub use double_map::StorageDoubleMap;
pub use key::{
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, Key, KeyGenerator,
KeyGeneratorMaxEncodedLen, ReversibleKeyGenerator, TupleToEncodedIter,
};
pub use map::StorageMap;
pub use nmap::StorageNMap;
pub use value::StorageValue;
/// Trait implementing how the storage optional value is converted into the queried type.
///
/// It is implemented by:
/// * `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.
const METADATA: StorageEntryModifierIR;
/// Type returned on query
type Query: FullCodec + 'static;
/// Convert an optional value (i.e. some if trie contains the value or none otherwise) to the
/// query.
fn from_optional_value_to_query(v: Option<Value>) -> Self::Query;
/// Convert a query to an optional value.
fn from_query_to_optional_value(v: Self::Query) -> Option<Value>;
}
/// Implement QueryKindTrait with query being `Option<Value>`
///
/// NOTE: it doesn't support a generic `OnEmpty`. This means only `None` can be
/// returned when no value is found. To use another `OnEmpty` implementation, `ValueQuery` can be
/// used instead.
pub struct OptionQuery;
impl<Value> QueryKindTrait<Value, crate::traits::GetDefault> for OptionQuery
where
Value: FullCodec + 'static,
{
const METADATA: StorageEntryModifierIR = StorageEntryModifierIR::Optional;
type Query = Option<Value>;
fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
// NOTE: OnEmpty is fixed to GetDefault, thus it returns `None` on no value.
v
}
fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
v
}
}
/// 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: StorageEntryModifierIR = StorageEntryModifierIR::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
where
Value: FullCodec + 'static,
OnEmpty: crate::traits::Get<Value>,
{
const METADATA: StorageEntryModifierIR = StorageEntryModifierIR::Default;
type Query = Value;
fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
v.unwrap_or_else(|| OnEmpty::get())
}
fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
Some(v)
}
}
/// Build the metadata of a storage.
///
/// Implemented by each of the storage types: value, map, countedmap, doublemap and nmap.
pub trait StorageEntryMetadataBuilder {
/// Build into `entries` the storage metadata entries of a storage given some `docs`.
fn build_metadata(doc: Vec<&'static str>, entries: &mut Vec<StorageEntryMetadataIR>);
}