mod double_map;
pub(crate) mod map;
mod nmap;
mod value;
pub use double_map::StorageDoubleMap;
pub use map::StorageMap;
pub use nmap::StorageNMap;
pub use value::StorageValue;
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use crate::{
assert_noop, assert_ok,
storage::{generator::StorageValue, unhashed, IterableStorageMap},
};
use codec::Encode;
use sp_io::TestExternalities;
struct Runtime;
pub trait Config: 'static {
type RuntimeOrigin;
type BlockNumber;
type PalletInfo: crate::traits::PalletInfo;
type DbWeight: crate::traits::Get<crate::weights::RuntimeDbWeight>;
}
impl Config for Runtime {
type RuntimeOrigin = u32;
type BlockNumber = u32;
type PalletInfo = crate::tests::PanicPalletInfo;
type DbWeight = ();
}
decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::RuntimeOrigin, system=self {}
}
crate::decl_storage! {
trait Store for Module<T: Config> as Runtime {
Value get(fn value) config(): (u64, u64);
NumberMap: map hasher(identity) u32 => u64;
DoubleMap: double_map hasher(identity) u32, hasher(identity) u32 => u64;
}
}
#[test]
fn value_translate_works() {
let t = GenesisConfig::default().build_storage().unwrap();
TestExternalities::new(t).execute_with(|| {
let key = Value::storage_value_final_key();
unhashed::put_raw(&key, &1111u32.encode());
let translate_fn = |old: Option<u32>| -> Option<(u64, u64)> {
old.map(|o| (o.into(), (o * 2).into()))
};
let res = Value::translate(translate_fn);
debug_assert!(res.is_ok());
assert_eq!(Value::get(), (1111, 2222));
})
}
#[test]
fn map_translate_works() {
let t = GenesisConfig::default().build_storage().unwrap();
TestExternalities::new(t).execute_with(|| {
for i in 0u32..100u32 {
unhashed::put(&NumberMap::hashed_key_for(&i), &(i as u64));
}
assert_eq!(
NumberMap::iter().collect::<Vec<_>>(),
(0..100).map(|x| (x as u32, x as u64)).collect::<Vec<_>>(),
);
NumberMap::translate(
|k: u32, v: u64| if k % 2 == 0 { Some((k as u64) << 32 | v) } else { None },
);
assert_eq!(
NumberMap::iter().collect::<Vec<_>>(),
(0..50u32)
.map(|x| x * 2)
.map(|x| (x, (x as u64) << 32 | x as u64))
.collect::<Vec<_>>(),
);
})
}
#[test]
fn try_mutate_works() {
let t = GenesisConfig::default().build_storage().unwrap();
TestExternalities::new(t).execute_with(|| {
assert_eq!(Value::get(), (0, 0));
assert_eq!(NumberMap::get(0), 0);
assert_eq!(DoubleMap::get(0, 0), 0);
assert_noop!(
Value::try_mutate(|value| -> Result<(), &'static str> {
*value = (2, 2);
Err("don't change value")
}),
"don't change value"
);
assert_noop!(
NumberMap::try_mutate(0, |value| -> Result<(), &'static str> {
*value = 4;
Err("don't change value")
}),
"don't change value"
);
assert_noop!(
DoubleMap::try_mutate(0, 0, |value| -> Result<(), &'static str> {
*value = 6;
Err("don't change value")
}),
"don't change value"
);
assert_eq!(Value::get(), (0, 0));
assert_eq!(NumberMap::get(0), 0);
assert_eq!(DoubleMap::get(0, 0), 0);
assert_ok!(Value::try_mutate(|value| -> Result<(), &'static str> {
*value = (2, 2);
Ok(())
}));
assert_ok!(NumberMap::try_mutate(0, |value| -> Result<(), &'static str> {
*value = 4;
Ok(())
}));
assert_ok!(DoubleMap::try_mutate(0, 0, |value| -> Result<(), &'static str> {
*value = 6;
Ok(())
}));
assert_eq!(Value::get(), (2, 2));
assert_eq!(NumberMap::get(0), 4);
assert_eq!(DoubleMap::get(0, 0), 6);
});
}
}