1use core::marker::PhantomData;
2
3use super::{
4 set_mapper::{self},
5 source::{CurrentStorage, StorageAddress},
6 SetMapper, StorageClearable, StorageMapper, StorageMapperFromAddress,
7};
8use crate::{
9 api::StorageMapperApi,
10 codec::{NestedDecode, NestedEncode, TopDecode, TopEncode},
11 contract_base::ErrorHelper,
12 storage::{self, StorageKey},
13 types::ManagedAddress,
14};
15
16const MAPPED_STORAGE_VALUE_IDENTIFIER: &[u8] = b".storage";
17type Keys<'a, SA, A, T> = set_mapper::Iter<'a, SA, A, T>;
18
19pub struct MapStorageMapper<SA, K, V, A = CurrentStorage>
20where
21 SA: StorageMapperApi,
22 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
23 A: StorageAddress<SA>,
24 V: StorageMapper<SA> + StorageClearable,
25{
26 _phantom_api: PhantomData<SA>,
27 base_key: StorageKey<SA>,
28 keys_set: SetMapper<SA, K, A>,
29 _phantom_value: PhantomData<V>,
30}
31
32impl<SA, K, V> StorageMapper<SA> for MapStorageMapper<SA, K, V, CurrentStorage>
33where
34 SA: StorageMapperApi,
35 K: TopEncode + TopDecode + NestedEncode + NestedDecode,
36 V: StorageMapper<SA> + StorageClearable,
37{
38 fn new(base_key: StorageKey<SA>) -> Self {
39 Self {
40 _phantom_api: PhantomData,
41 base_key: base_key.clone(),
42 keys_set: SetMapper::new(base_key),
43 _phantom_value: PhantomData,
44 }
45 }
46}
47
48impl<SA, K, V> StorageClearable for MapStorageMapper<SA, K, V, CurrentStorage>
49where
50 SA: StorageMapperApi,
51 K: TopEncode + TopDecode + NestedEncode + NestedDecode,
52 V: StorageMapper<SA> + StorageClearable,
53{
54 fn clear(&mut self) {
55 for mut value in self.values() {
56 value.clear();
57 }
58 self.keys_set.clear();
59 }
60}
61
62impl<SA, K, V> MapStorageMapper<SA, K, V, CurrentStorage>
63where
64 SA: StorageMapperApi,
65 K: TopEncode + TopDecode + NestedEncode + NestedDecode,
66 V: StorageMapper<SA> + StorageClearable,
67{
68 pub fn insert_default(&mut self, k: K) -> bool {
74 self.keys_set.insert(k)
75 }
76
77 pub fn remove(&mut self, k: &K) -> bool {
83 if self.keys_set.remove(k) {
84 self.get_mapped_storage_value(k).clear();
85 return true;
86 }
87 false
88 }
89}
90
91impl<SA, K, V> StorageMapperFromAddress<SA> for MapStorageMapper<SA, K, V, ManagedAddress<SA>>
92where
93 SA: StorageMapperApi,
94 K: TopEncode + TopDecode + NestedEncode + NestedDecode,
95 V: StorageMapper<SA> + StorageClearable,
96{
97 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
98 MapStorageMapper {
99 _phantom_api: PhantomData,
100 base_key: base_key.clone(),
101 keys_set: SetMapper::new_from_address(address, base_key),
102 _phantom_value: PhantomData,
103 }
104 }
105}
106
107impl<SA, A, K, V> MapStorageMapper<SA, K, V, A>
108where
109 SA: StorageMapperApi,
110 A: StorageAddress<SA>,
111 K: TopEncode + TopDecode + NestedEncode + NestedDecode,
112 V: StorageMapper<SA> + StorageClearable,
113{
114 fn build_named_key(&self, name: &[u8], key: &K) -> StorageKey<SA> {
115 let mut named_key = self.base_key.clone();
116 named_key.append_bytes(name);
117 named_key.append_item(key);
118 named_key
119 }
120
121 fn get_mapped_storage_value(&self, key: &K) -> V {
122 let key = self.build_named_key(MAPPED_STORAGE_VALUE_IDENTIFIER, key);
123 <V as storage::mappers::StorageMapper<SA>>::new(key)
124 }
125
126 pub fn get(&self, k: &K) -> Option<V> {
128 if self.keys_set.contains(k) {
129 return Some(self.get_mapped_storage_value(k));
130 }
131 None
132 }
133
134 pub fn keys(&self) -> Keys<'_, SA, A, K> {
135 self.keys_set.iter()
136 }
137
138 pub fn is_empty(&self) -> bool {
140 self.keys_set.is_empty()
141 }
142
143 pub fn len(&self) -> usize {
145 self.keys_set.len()
146 }
147
148 pub fn contains_key(&self, k: &K) -> bool {
150 self.keys_set.contains(k)
151 }
152
153 pub fn entry(&mut self, key: K) -> Entry<'_, SA, A, K, V> {
155 if self.contains_key(&key) {
156 Entry::Occupied(OccupiedEntry {
157 key,
158 map: self,
159 _marker: PhantomData,
160 })
161 } else {
162 Entry::Vacant(VacantEntry {
163 key,
164 map: self,
165 _marker: PhantomData,
166 })
167 }
168 }
169
170 pub fn values(&self) -> Values<'_, SA, A, K, V> {
173 Values::new(self)
174 }
175
176 pub fn iter(&self) -> Iter<'_, SA, A, K, V> {
179 Iter::new(self)
180 }
181}
182
183impl<'a, SA, A, K, V> IntoIterator for &'a MapStorageMapper<SA, K, V, A>
184where
185 SA: StorageMapperApi,
186 A: StorageAddress<SA>,
187 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
188 V: StorageMapper<SA> + StorageClearable,
189{
190 type Item = (K, V);
191
192 type IntoIter = Iter<'a, SA, A, K, V>;
193
194 fn into_iter(self) -> Self::IntoIter {
195 self.iter()
196 }
197}
198
199pub struct Iter<'a, SA, A, K, V>
200where
201 SA: StorageMapperApi,
202 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
203 A: StorageAddress<SA>,
204 V: StorageMapper<SA> + StorageClearable,
205{
206 key_iter: Keys<'a, SA, A, K>,
207 hash_map: &'a MapStorageMapper<SA, K, V, A>,
208}
209
210impl<'a, SA, A, K, V> Iter<'a, SA, A, K, V>
211where
212 SA: StorageMapperApi,
213 A: StorageAddress<SA>,
214 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
215 V: StorageMapper<SA> + StorageClearable,
216{
217 fn new(hash_map: &'a MapStorageMapper<SA, K, V, A>) -> Iter<'a, SA, A, K, V> {
218 Iter {
219 key_iter: hash_map.keys(),
220 hash_map,
221 }
222 }
223}
224
225impl<SA, A, K, V> Iterator for Iter<'_, SA, A, K, V>
226where
227 SA: StorageMapperApi,
228 A: StorageAddress<SA>,
229 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
230 V: StorageMapper<SA> + StorageClearable,
231{
232 type Item = (K, V);
233
234 #[inline]
235 fn next(&mut self) -> Option<(K, V)> {
236 if let Some(key) = self.key_iter.next() {
237 let Some(value) = self.hash_map.get(&key) else {
238 ErrorHelper::<SA>::signal_error_with_message("missing key")
239 };
240 return Some((key, value));
241 }
242 None
243 }
244}
245
246pub struct Values<'a, SA, A, K, V>
247where
248 SA: StorageMapperApi,
249 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
250 A: StorageAddress<SA>,
251 V: StorageMapper<SA> + StorageClearable,
252{
253 key_iter: Keys<'a, SA, A, K>,
254 hash_map: &'a MapStorageMapper<SA, K, V, A>,
255}
256
257impl<'a, SA, A, K, V> Values<'a, SA, A, K, V>
258where
259 SA: StorageMapperApi,
260 A: StorageAddress<SA>,
261 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
262 V: StorageMapper<SA> + StorageClearable,
263{
264 fn new(hash_map: &'a MapStorageMapper<SA, K, V, A>) -> Values<'a, SA, A, K, V> {
265 Values {
266 key_iter: hash_map.keys(),
267 hash_map,
268 }
269 }
270}
271
272impl<SA, A, K, V> Iterator for Values<'_, SA, A, K, V>
273where
274 SA: StorageMapperApi,
275 A: StorageAddress<SA>,
276 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
277 V: StorageMapper<SA> + StorageClearable,
278{
279 type Item = V;
280
281 #[inline]
282 fn next(&mut self) -> Option<V> {
283 if let Some(key) = self.key_iter.next() {
284 let value = self.hash_map.get(&key).unwrap();
285 return Some(value);
286 }
287 None
288 }
289}
290
291pub enum Entry<'a, SA, A, K: 'a, V: 'a>
292where
293 SA: StorageMapperApi,
294 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
295 A: StorageAddress<SA>,
296 V: StorageMapper<SA> + StorageClearable,
297{
298 Vacant(VacantEntry<'a, SA, A, K, V>),
300
301 Occupied(OccupiedEntry<'a, SA, A, K, V>),
303}
304
305pub struct VacantEntry<'a, SA, A, K: 'a, V: 'a>
308where
309 SA: StorageMapperApi,
310 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
311 A: StorageAddress<SA>,
312 V: StorageMapper<SA> + StorageClearable,
313{
314 pub(super) key: K,
315 pub(super) map: &'a mut MapStorageMapper<SA, K, V, A>,
316
317 pub(super) _marker: PhantomData<&'a mut (K, V)>,
319}
320
321pub struct OccupiedEntry<'a, SA, A, K: 'a, V: 'a>
324where
325 SA: StorageMapperApi,
326 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
327 A: StorageAddress<SA>,
328 V: StorageMapper<SA> + StorageClearable,
329{
330 pub(super) key: K,
331 pub(super) map: &'a mut MapStorageMapper<SA, K, V, A>,
332
333 pub(super) _marker: PhantomData<&'a mut (K, V)>,
335}
336
337impl<'a, SA, K, V> Entry<'a, SA, CurrentStorage, K, V>
338where
339 SA: StorageMapperApi,
340 K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
341 V: StorageMapper<SA> + StorageClearable,
342{
343 pub fn or_insert_default(self) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> {
346 match self {
347 Entry::Occupied(entry) => entry,
348 Entry::Vacant(entry) => entry.insert_default(),
349 }
350 }
351
352 pub fn key(&self) -> &K {
354 match *self {
355 Entry::Occupied(ref entry) => entry.key(),
356 Entry::Vacant(ref entry) => entry.key(),
357 }
358 }
359
360 pub fn and_modify<F>(self, f: F) -> Self
363 where
364 F: FnOnce(&mut V),
365 {
366 match self {
367 Entry::Occupied(mut entry) => {
368 entry.update(f);
369 Entry::Occupied(entry)
370 }
371 Entry::Vacant(entry) => Entry::Vacant(entry),
372 }
373 }
374}
375
376impl<'a, SA, K, V> Entry<'a, SA, CurrentStorage, K, V>
377where
378 SA: StorageMapperApi,
379 K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
380 V: StorageMapper<SA> + StorageClearable,
381{
382 pub fn or_default(self) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> {
385 match self {
386 Entry::Occupied(entry) => entry,
387 Entry::Vacant(entry) => entry.insert_default(),
388 }
389 }
390}
391
392impl<SA, A, K, V> VacantEntry<'_, SA, A, K, V>
393where
394 SA: StorageMapperApi,
395 A: StorageAddress<SA>,
396 K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
397 V: StorageMapper<SA> + StorageClearable,
398{
399 pub fn key(&self) -> &K {
402 &self.key
403 }
404}
405
406impl<'a, SA, K, V> VacantEntry<'a, SA, CurrentStorage, K, V>
407where
408 SA: StorageMapperApi,
409 K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
410 V: StorageMapper<SA> + StorageClearable,
411{
412 pub fn insert_default(self) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> {
415 self.map.insert_default(self.key.clone());
416 OccupiedEntry {
417 key: self.key,
418 map: self.map,
419 _marker: PhantomData,
420 }
421 }
422}
423
424impl<SA, A, K, V> OccupiedEntry<'_, SA, A, K, V>
425where
426 SA: StorageMapperApi,
427 A: StorageAddress<SA>,
428 K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
429 V: StorageMapper<SA> + StorageClearable,
430{
431 pub fn key(&self) -> &K {
433 &self.key
434 }
435
436 pub fn get(&self) -> V {
438 self.map.get(&self.key).unwrap()
439 }
440}
441
442impl<SA, K, V> OccupiedEntry<'_, SA, CurrentStorage, K, V>
443where
444 SA: StorageMapperApi,
445 K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
446 V: StorageMapper<SA> + StorageClearable,
447{
448 pub fn update<R, F: FnOnce(&mut V) -> R>(&mut self, f: F) -> R {
452 let mut value = self.get();
453 f(&mut value)
454 }
455
456 pub fn remove(self) {
458 self.map.remove(&self.key);
459 }
460}