1use alloc::collections::BTreeMap;
2use core::fmt;
3#[cfg(feature = "iterator")]
4use core::iter;
5#[cfg(feature = "iterator")]
6use core::ops::{Bound, RangeBounds};
7
8#[cfg(feature = "iterator")]
9use crate::iterator::{Order, Record};
10use crate::prelude::*;
11use crate::traits::Storage;
12
13#[derive(Default)]
14pub struct MockStorage {
15 data: BTreeMap<Vec<u8>, Vec<u8>>,
16}
17
18impl MockStorage {
19 pub fn new() -> Self {
20 MockStorage::default()
21 }
22}
23
24impl Storage for MockStorage {
25 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
26 self.data.get(key).cloned()
27 }
28
29 fn set(&mut self, key: &[u8], value: &[u8]) {
30 if value.is_empty() {
31 panic!("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.");
32 }
33
34 self.data.insert(key.to_vec(), value.to_vec());
35 }
36
37 fn remove(&mut self, key: &[u8]) {
38 self.data.remove(key);
39 }
40
41 #[cfg(feature = "iterator")]
42 fn range<'a>(
45 &'a self,
46 start: Option<&[u8]>,
47 end: Option<&[u8]>,
48 order: Order,
49 ) -> Box<dyn Iterator<Item = Record> + 'a> {
50 let bounds = range_bounds(start, end);
51
52 match (bounds.start_bound(), bounds.end_bound()) {
55 (Bound::Included(start), Bound::Excluded(end)) if start > end => {
56 return Box::new(iter::empty());
57 }
58 _ => {}
59 }
60
61 let iter = self.data.range(bounds);
62 match order {
63 Order::Ascending => Box::new(iter.map(clone_item)),
64 Order::Descending => Box::new(iter.rev().map(clone_item)),
65 }
66 }
67}
68
69impl fmt::Debug for MockStorage {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(f, "MemoryStorage ({} entries)", self.data.len())?;
74 f.write_str(" {\n")?;
75 for (key, value) in &self.data {
76 f.write_str(" 0x")?;
77 for byte in key {
78 write!(f, "{byte:02x}")?;
79 }
80 f.write_str(": 0x")?;
81 for byte in value {
82 write!(f, "{byte:02x}")?;
83 }
84 f.write_str("\n")?;
85 }
86 f.write_str("}")?;
87 Ok(())
88 }
89}
90
91#[cfg(feature = "iterator")]
92fn range_bounds(start: Option<&[u8]>, end: Option<&[u8]>) -> impl RangeBounds<Vec<u8>> {
93 (
94 start.map_or(Bound::Unbounded, |x| Bound::Included(x.to_vec())),
95 end.map_or(Bound::Unbounded, |x| Bound::Excluded(x.to_vec())),
96 )
97}
98
99#[cfg(feature = "iterator")]
100type BTreeMapRecordRef<'a> = (&'a Vec<u8>, &'a Vec<u8>);
103
104#[cfg(feature = "iterator")]
105fn clone_item(item_ref: BTreeMapRecordRef) -> Record {
106 let (key, value) = item_ref;
107 (key.clone(), value.clone())
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn get_and_set() {
116 let mut store = MockStorage::new();
117 assert_eq!(store.get(b"foo"), None);
118 store.set(b"foo", b"bar");
119 assert_eq!(store.get(b"foo"), Some(b"bar".to_vec()));
120 assert_eq!(store.get(b"food"), None);
121 }
122
123 #[test]
124 #[should_panic(
125 expected = "Getting empty values from storage is not well supported at the moment."
126 )]
127 fn set_panics_for_empty() {
128 let mut store = MockStorage::new();
129 store.set(b"foo", b"");
130 }
131
132 #[test]
133 fn delete() {
134 let mut store = MockStorage::new();
135 store.set(b"foo", b"bar");
136 store.set(b"food", b"bank");
137 store.remove(b"foo");
138
139 assert_eq!(store.get(b"foo"), None);
140 assert_eq!(store.get(b"food"), Some(b"bank".to_vec()));
141 }
142
143 #[test]
144 #[cfg(feature = "iterator")]
145 fn iterator() {
146 let mut store = MockStorage::new();
147 store.set(b"foo", b"bar");
148
149 assert_eq!(store.get(b"foo"), Some(b"bar".to_vec()));
151 assert_eq!(store.range(None, None, Order::Ascending).count(), 1);
152
153 store.set(b"ant", b"hill");
155 store.set(b"ze", b"bra");
156
157 store.set(b"bye", b"bye");
159 store.remove(b"bye");
160
161 {
163 let iter = store.range(None, None, Order::Ascending);
164 let elements: Vec<Record> = iter.collect();
165 assert_eq!(
166 elements,
167 vec![
168 (b"ant".to_vec(), b"hill".to_vec()),
169 (b"foo".to_vec(), b"bar".to_vec()),
170 (b"ze".to_vec(), b"bra".to_vec()),
171 ]
172 );
173 }
174
175 {
177 let iter = store.range(None, None, Order::Descending);
178 let elements: Vec<Record> = iter.collect();
179 assert_eq!(
180 elements,
181 vec![
182 (b"ze".to_vec(), b"bra".to_vec()),
183 (b"foo".to_vec(), b"bar".to_vec()),
184 (b"ant".to_vec(), b"hill".to_vec()),
185 ]
186 );
187 }
188
189 {
191 let iter = store.range(Some(b"f"), Some(b"n"), Order::Ascending);
192 let elements: Vec<Record> = iter.collect();
193 assert_eq!(elements, vec![(b"foo".to_vec(), b"bar".to_vec())]);
194 }
195
196 {
198 let iter = store.range(Some(b"air"), Some(b"loop"), Order::Descending);
199 let elements: Vec<Record> = iter.collect();
200 assert_eq!(
201 elements,
202 vec![
203 (b"foo".to_vec(), b"bar".to_vec()),
204 (b"ant".to_vec(), b"hill".to_vec()),
205 ]
206 );
207 }
208
209 {
211 let iter = store.range(Some(b"foo"), Some(b"foo"), Order::Ascending);
212 let elements: Vec<Record> = iter.collect();
213 assert_eq!(elements, vec![]);
214 }
215
216 {
218 let iter = store.range(Some(b"foo"), Some(b"foo"), Order::Descending);
219 let elements: Vec<Record> = iter.collect();
220 assert_eq!(elements, vec![]);
221 }
222
223 {
225 let iter = store.range(Some(b"z"), Some(b"a"), Order::Ascending);
226 let elements: Vec<Record> = iter.collect();
227 assert_eq!(elements, vec![]);
228 }
229
230 {
232 let iter = store.range(Some(b"z"), Some(b"a"), Order::Descending);
233 let elements: Vec<Record> = iter.collect();
234 assert_eq!(elements, vec![]);
235 }
236
237 {
239 let iter = store.range(Some(b"f"), None, Order::Ascending);
240 let elements: Vec<Record> = iter.collect();
241 assert_eq!(
242 elements,
243 vec![
244 (b"foo".to_vec(), b"bar".to_vec()),
245 (b"ze".to_vec(), b"bra".to_vec()),
246 ]
247 );
248 }
249
250 {
252 let iter = store.range(Some(b"f"), None, Order::Descending);
253 let elements: Vec<Record> = iter.collect();
254 assert_eq!(
255 elements,
256 vec![
257 (b"ze".to_vec(), b"bra".to_vec()),
258 (b"foo".to_vec(), b"bar".to_vec()),
259 ]
260 );
261 }
262
263 {
265 let iter = store.range(None, Some(b"f"), Order::Ascending);
266 let elements: Vec<Record> = iter.collect();
267 assert_eq!(elements, vec![(b"ant".to_vec(), b"hill".to_vec()),]);
268 }
269
270 {
272 let iter = store.range(None, Some(b"no"), Order::Descending);
273 let elements: Vec<Record> = iter.collect();
274 assert_eq!(
275 elements,
276 vec![
277 (b"foo".to_vec(), b"bar".to_vec()),
278 (b"ant".to_vec(), b"hill".to_vec()),
279 ]
280 );
281 }
282 }
283
284 #[test]
285 fn memory_storage_implements_debug() {
286 let store = MockStorage::new();
287 assert_eq!(
288 format!("{store:?}"),
289 "MemoryStorage (0 entries) {\n\
290 }"
291 );
292
293 let mut store = MockStorage::new();
295 store.set(&[0x00, 0xAB, 0xDD], &[0xFF, 0xD5]);
296 assert_eq!(
297 format!("{store:?}"),
298 "MemoryStorage (1 entries) {\n\
299 \x20\x200x00abdd: 0xffd5\n\
300 }"
301 );
302
303 let mut store = MockStorage::new();
305 store.set(&[0x00, 0xAB, 0xDD], &[0xFF, 0xD5]);
306 store.set(&[0x00, 0xAB, 0xEE], &[0xFF, 0xD5]);
307 store.set(&[0x00, 0xAB, 0xCC], &[0xFF, 0xD5]);
308 assert_eq!(
309 format!("{store:?}"),
310 "MemoryStorage (3 entries) {\n\
311 \x20\x200x00abcc: 0xffd5\n\
312 \x20\x200x00abdd: 0xffd5\n\
313 \x20\x200x00abee: 0xffd5\n\
314 }"
315 );
316
317 let mut store = MockStorage::new();
319 store.set(&[0xAA], &[0x11]);
320 store.set(&[0xAA, 0xBB], &[0x11, 0x22]);
321 store.set(&[0xAA, 0xBB, 0xCC], &[0x11, 0x22, 0x33]);
322 store.set(&[0xAA, 0xBB, 0xCC, 0xDD], &[0x11, 0x22, 0x33, 0x44]);
323 assert_eq!(
324 format!("{store:?}"),
325 "MemoryStorage (4 entries) {\n\
326 \x20\x200xaa: 0x11\n\
327 \x20\x200xaabb: 0x1122\n\
328 \x20\x200xaabbcc: 0x112233\n\
329 \x20\x200xaabbccdd: 0x11223344\n\
330 }"
331 );
332 }
333}