use frame_support::codec::{Encode, EncodeAppend, EncodeLike};
pub trait MapStorage {
type Key;
type Value;
fn contains_key(key: &Self::Key) -> bool;
fn get(key: &Self::Key) -> Option<Self::Value>;
fn insert(key: Self::Key, value: Self::Value);
fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(key: Self::Key, f: F) -> R;
fn mutate_exists<R, F: FnOnce(&mut Self::Value) -> R>(key: Self::Key, f: F) -> Option<R> {
Self::mutate(key, |opt_val| opt_val.as_mut().map(f))
}
fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(f: F);
fn remove(key: Self::Key);
fn clear();
fn take(key: Self::Key) -> Option<Self::Value>;
}
pub trait AppendMapStorage<Item, Key, Value>: MapStorage<Key = Key, Value = Value>
where
Item: Encode,
Key: Encode,
Value: EncodeAppend<Item = Item>,
{
fn append<EncodeLikeKey, EncodeLikeItem>(key: EncodeLikeKey, item: EncodeLikeItem)
where
EncodeLikeKey: EncodeLike<Key>,
EncodeLikeItem: EncodeLike<Item>;
}
#[allow(clippy::crate_in_macro_def)]
#[macro_export]
macro_rules! wrap_storage_map {
(storage: $storage: ident, name: $name: ident, key: $key: ty, value: $val: ty) => {
pub struct $name<T>(PhantomData<T>);
impl<T: crate::Config> MapStorage for $name<T> {
type Key = $key;
type Value = $val;
fn contains_key(key: &Self::Key) -> bool {
$storage::<T>::contains_key(key)
}
fn get(key: &Self::Key) -> Option<Self::Value> {
$storage::<T>::get(key)
}
fn insert(key: Self::Key, value: Self::Value) {
$storage::<T>::insert(key, value)
}
fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(key: Self::Key, f: F) -> R {
$storage::<T>::mutate(key, f)
}
fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(mut f: F) {
let f = |v| Some(f(v));
$storage::<T>::translate_values(f)
}
fn remove(key: Self::Key) {
$storage::<T>::remove(key)
}
fn clear() {
let _ = $storage::<T>::clear(u32::MAX, None);
}
fn take(key: Self::Key) -> Option<Self::Value> {
$storage::<T>::take(key)
}
}
};
}
#[allow(clippy::crate_in_macro_def)]
#[macro_export]
macro_rules! wrap_counted_storage_map {
(storage: $storage: ident, name: $name: ident, key: $key: ty, value: $val: ty, length: $len: ty) => {
$crate::wrap_storage_map!(storage: $storage, name: $name, key: $key, value: $val);
impl<T: crate::Config> Counted for $name<T> {
type Length = $len;
fn len() -> Self::Length {
$storage::<T>::count() as Self::Length
}
}
};
}