ownable_std/
memory_storage.rs1use cosmwasm_std::Order;
2use cosmwasm_std::Storage;
3use std::collections::BTreeMap;
4use std::iter;
5use std::ops::{Bound, RangeBounds};
6
7#[derive(Default)]
8pub struct MemoryStorage {
10 data: BTreeMap<Vec<u8>, Vec<u8>>,
11}
12
13impl MemoryStorage {
14 pub fn new() -> Self {
16 Self::default()
17 }
18}
19
20impl Storage for MemoryStorage {
21 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
22 self.data.get(key).cloned()
23 }
24
25 fn set(&mut self, key: &[u8], value: &[u8]) {
26 if value.is_empty() {
27 panic!(
28 "TL;DR: Value must not be empty in Storage::set but in most cases you can use Storage::remove instead. Long story: Getting empty values from storage is not well supported at the moment. Some of our internal interfaces cannot differentiate between a non-existent key and an empty value. Right now, you cannot rely on the behaviour of empty values. To protect you from trouble later on, we stop here. Sorry for the inconvenience! We highly welcome you to contribute to CosmWasm, making this more solid one way or the other."
29 );
30 }
31
32 self.data.insert(key.to_vec(), value.to_vec());
33 }
34
35 fn remove(&mut self, key: &[u8]) {
36 self.data.remove(key);
37 }
38
39 fn range<'a>(
40 &'a self,
41 start: Option<&[u8]>,
42 end: Option<&[u8]>,
43 order: Order,
44 ) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a> {
45 let bounds = range_bounds(start, end);
46
47 match (bounds.start_bound(), bounds.end_bound()) {
48 (Bound::Included(start), Bound::Excluded(end)) if start > end => {
49 return Box::new(iter::empty());
50 }
51 _ => {}
52 }
53
54 let iter = self.data.range(bounds);
55 match order {
56 Order::Ascending => Box::new(iter.map(clone_item)),
57 Order::Descending => Box::new(iter.rev().map(clone_item)),
58 }
59 }
60}
61
62fn range_bounds(start: Option<&[u8]>, end: Option<&[u8]>) -> impl RangeBounds<Vec<u8>> {
63 (
64 start.map_or(Bound::Unbounded, |x| Bound::Included(x.to_vec())),
65 end.map_or(Bound::Unbounded, |x| Bound::Excluded(x.to_vec())),
66 )
67}
68
69type BTreeMapRecordRef<'a> = (&'a Vec<u8>, &'a Vec<u8>);
70
71fn clone_item(item_ref: BTreeMapRecordRef) -> (Vec<u8>, Vec<u8>) {
72 let (key, value) = item_ref;
73 (key.clone(), value.clone())
74}