pub trait DoubleMapStorage {
type Key1;
type Key2;
type Value;
fn contains_keys(key1: &Self::Key1, key2: &Self::Key2) -> bool;
fn get(key1: &Self::Key1, key2: &Self::Key2) -> Option<Self::Value>;
fn insert(key1: Self::Key1, key2: Self::Key2, value: Self::Value);
fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(
key1: Self::Key1,
key2: Self::Key2,
f: F,
) -> R;
fn mutate_exists<R, F: FnOnce(&mut Self::Value) -> R>(
key1: Self::Key1,
key2: Self::Key2,
f: F,
) -> Option<R> {
Self::mutate(key1, key2, |opt_val| opt_val.as_mut().map(f))
}
fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(f: F);
fn remove(key1: Self::Key1, key2: Self::Key2);
fn clear();
fn take(key1: Self::Key1, key2: Self::Key2) -> Option<Self::Value>;
fn clear_prefix(first_key: Self::Key1);
}
#[allow(clippy::crate_in_macro_def)]
#[macro_export]
macro_rules! wrap_storage_double_map {
(storage: $storage: ident, name: $name: ident, key1: $key1: ty,
key2: $key2: ty, value: $val: ty) => {
pub struct $name<T>(PhantomData<T>);
impl<T: crate::Config> DoubleMapStorage for $name<T> {
type Key1 = $key1;
type Key2 = $key2;
type Value = $val;
fn contains_keys(key1: &Self::Key1, key2: &Self::Key2) -> bool {
$storage::<T>::contains_key(key1, key2)
}
fn get(key1: &Self::Key1, key2: &Self::Key2) -> Option<Self::Value> {
$storage::<T>::get(key1, key2)
}
fn insert(key1: Self::Key1, key2: Self::Key2, value: Self::Value) {
$storage::<T>::insert(key1, key2, value)
}
fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(
key1: Self::Key1,
key2: Self::Key2,
f: F,
) -> R {
$storage::<T>::mutate(key1, key2, 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(key1: Self::Key1, key2: Self::Key2) {
$storage::<T>::remove(key1, key2)
}
fn clear() {
let _ = $storage::<T>::clear(u32::MAX, None);
}
fn take(key1: Self::Key1, key2: Self::Key2) -> Option<Self::Value> {
$storage::<T>::take(key1, key2)
}
fn clear_prefix(first_key: Self::Key1) {
let _ = $storage::<T>::clear_prefix(first_key, u32::MAX, None);
}
}
};
}
#[allow(clippy::crate_in_macro_def)]
#[macro_export]
macro_rules! wrap_extended_storage_double_map {
(storage: $storage: ident, name: $name: ident, key1: $key1: ty,
key2: $key2: ty, value: $val: ty, length: $len: ty) => {
$crate::wrap_storage_double_map!(
storage: $storage,
name: $name,
key1: $key1,
key2: $key2,
value: $val
);
impl<T: crate::Config> CountedByKey for $name<T> {
type Key = $key1;
type Length = $len;
fn len(key: &Self::Key) -> Self::Length {
$storage::<T>::iter_prefix(key).count()
}
}
impl<T: crate::Config> IterableByKeyMap<$val> for $name<T> {
type Key = $key1;
type DrainIter = IteratorWrap<PrefixIterator<($key2, $val)>, $val, GetSecondPos>;
type Iter = IteratorWrap<PrefixIterator<($key2, $val)>, $val, GetSecondPos>;
fn drain_key(key: Self::Key) -> Self::DrainIter {
$storage::<T>::drain_prefix(key).into()
}
fn iter_key(key: Self::Key) -> Self::Iter {
$storage::<T>::iter_prefix(key).into()
}
}
impl<T: crate::Config> IterableMap<$val> for $name<T> {
type DrainIter = IteratorWrap<PrefixIterator<($key1, $key2, $val)>, $val, GetThirdPos>;
type Iter = IteratorWrap<PrefixIterator<($key1, $key2, $val)>, $val, GetThirdPos>;
fn drain() -> Self::DrainIter {
$storage::<T>::drain().into()
}
fn iter() -> Self::Iter {
$storage::<T>::iter().into()
}
}
impl<T: crate::Config> KeyIterableByKeyMap for $name<T> {
type Key1 = $key1;
type Key2 = $key2;
type DrainIter = IteratorWrap<PrefixIterator<($key2, $val)>, $key2, GetFirstPos>;
type Iter = IteratorWrap<PrefixIterator<($key2, $val)>, $key2, GetFirstPos>;
fn drain_prefix_keys(key: Self::Key1) -> Self::DrainIter {
$storage::<T>::drain_prefix(key).into()
}
fn iter_prefix_keys(key: Self::Key1) -> Self::Iter {
$storage::<T>::iter_prefix(key).into()
}
}
};
}