use super::changeset::OverlayedMap;
use sp_core::offchain::OffchainOverlayedChange;
use sp_std::prelude::Vec;
#[derive(Debug, Clone, Default)]
pub struct OffchainOverlayedChanges(OverlayedMap<(Vec<u8>, Vec<u8>), OffchainOverlayedChange>);
type OffchainOverlayedChangesItem<'i> = (&'i (Vec<u8>, Vec<u8>), &'i OffchainOverlayedChange);
type OffchainOverlayedChangesItemOwned = ((Vec<u8>, Vec<u8>), OffchainOverlayedChange);
impl OffchainOverlayedChanges {
pub fn into_iter(self) -> impl Iterator<Item = OffchainOverlayedChangesItemOwned> {
self.0.into_changes().map(|kv| (kv.0, kv.1.into_value()))
}
pub fn iter(&self) -> impl Iterator<Item = OffchainOverlayedChangesItem> {
self.0.changes().map(|kv| (kv.0, kv.1.value_ref()))
}
pub fn drain(&mut self) -> impl Iterator<Item = OffchainOverlayedChangesItemOwned> {
sp_std::mem::take(self).into_iter()
}
pub fn remove(&mut self, prefix: &[u8], key: &[u8]) {
let _ = self
.0
.set((prefix.to_vec(), key.to_vec()), OffchainOverlayedChange::Remove, None);
}
pub fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) {
let _ = self.0.set(
(prefix.to_vec(), key.to_vec()),
OffchainOverlayedChange::SetValue(value.to_vec()),
None,
);
}
pub fn get(&self, prefix: &[u8], key: &[u8]) -> Option<OffchainOverlayedChange> {
let key = (prefix.to_vec(), key.to_vec());
self.0.get(&key).map(|entry| entry.value_ref()).cloned()
}
pub fn overlay(&self) -> &OverlayedMap<(Vec<u8>, Vec<u8>), OffchainOverlayedChange> {
&self.0
}
pub fn overlay_mut(
&mut self,
) -> &mut OverlayedMap<(Vec<u8>, Vec<u8>), OffchainOverlayedChange> {
&mut self.0
}
}
#[cfg(test)]
mod test {
use super::*;
use sp_core::offchain::STORAGE_PREFIX;
#[test]
fn test_drain() {
let mut ooc = OffchainOverlayedChanges::default();
ooc.set(STORAGE_PREFIX, b"kkk", b"vvv");
let drained = ooc.drain().count();
assert_eq!(drained, 1);
let leftover = ooc.iter().count();
assert_eq!(leftover, 0);
ooc.set(STORAGE_PREFIX, b"a", b"v");
ooc.set(STORAGE_PREFIX, b"b", b"v");
ooc.set(STORAGE_PREFIX, b"c", b"v");
ooc.set(STORAGE_PREFIX, b"d", b"v");
ooc.set(STORAGE_PREFIX, b"e", b"v");
assert_eq!(ooc.iter().count(), 5);
}
#[test]
fn test_accumulated_set_remove_set() {
let mut ooc = OffchainOverlayedChanges::default();
ooc.set(STORAGE_PREFIX, b"ppp", b"qqq");
ooc.remove(STORAGE_PREFIX, b"ppp");
assert_eq!(ooc.iter().count(), 1);
ooc.set(STORAGE_PREFIX, b"ppp", b"rrr");
let mut iter = ooc.into_iter();
assert_eq!(
iter.next(),
Some((
(STORAGE_PREFIX.to_vec(), b"ppp".to_vec()),
OffchainOverlayedChange::SetValue(b"rrr".to_vec())
))
);
assert_eq!(iter.next(), None);
}
}