fuel_merkle/common/
storage_map.rs1use crate::{
2 alloc::borrow::ToOwned,
3 storage::{
4 Mappable,
5 StorageInspect,
6 StorageMutate,
7 },
8};
9
10use alloc::borrow::Cow;
11use hashbrown::HashMap;
12
13#[derive(Debug, Clone)]
14pub struct StorageMap<Type>
15where
16 Type: Mappable,
17{
18 map: HashMap<Type::OwnedKey, Type::OwnedValue>,
19}
20
21impl<Type> Default for StorageMap<Type>
22where
23 Type: Mappable,
24{
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl<Type> StorageMap<Type>
31where
32 Type: Mappable,
33{
34 pub fn new() -> Self {
35 Self {
36 map: Default::default(),
37 }
38 }
39
40 pub fn is_empty(&self) -> bool {
41 self.map.is_empty()
42 }
43
44 pub fn len(&self) -> usize {
45 self.map.len()
46 }
47}
48
49impl<Type> StorageInspect<Type> for StorageMap<Type>
50where
51 Type: Mappable,
52 Type::Key: Eq + core::hash::Hash,
53 Type::OwnedKey: Eq + core::hash::Hash + core::borrow::Borrow<Type::Key>,
54{
55 type Error = core::convert::Infallible;
56
57 fn get(&self, key: &Type::Key) -> Result<Option<Cow<Type::OwnedValue>>, Self::Error> {
58 let result = self.map.get(key);
59 let value = result.map(Cow::Borrowed);
60 Ok(value)
61 }
62
63 fn contains_key(&self, key: &Type::Key) -> Result<bool, Self::Error> {
64 let contains = self.map.contains_key(key);
65 Ok(contains)
66 }
67}
68
69impl<Type> StorageMutate<Type> for StorageMap<Type>
70where
71 Type: Mappable,
72 Type::Key: Eq + core::hash::Hash,
73 Type::OwnedKey: Eq + core::hash::Hash + core::borrow::Borrow<Type::Key>,
74{
75 fn replace(
76 &mut self,
77 key: &Type::Key,
78 value: &Type::Value,
79 ) -> Result<Option<Type::OwnedValue>, Self::Error> {
80 let previous = self
81 .map
82 .insert(key.to_owned().into(), value.to_owned().into());
83 Ok(previous)
84 }
85
86 fn take(&mut self, key: &Type::Key) -> Result<Option<Type::OwnedValue>, Self::Error> {
87 let value = self.map.remove(key);
88 Ok(value)
89 }
90}
91
92#[cfg(test)]
93mod test {
94 use super::*;
95
96 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
97 struct TestKey(u32);
98
99 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
100 struct TestValue(u32);
101
102 struct TestTable;
103
104 impl Mappable for TestTable {
105 type Key = Self::OwnedKey;
106 type OwnedKey = TestKey;
107 type OwnedValue = TestValue;
108 type Value = Self::OwnedValue;
109 }
110
111 #[test]
112 fn test_get_returns_value_for_given_key() {
113 let key = TestKey(0);
114 let mut store = StorageMap::<TestTable>::new();
115 let _ = store.insert(&key, &TestValue(0));
116
117 assert_eq!(store.get(&key).unwrap(), Some(Cow::Borrowed(&TestValue(0))));
118 }
119 #[test]
120 fn test_get_returns_none_for_invalid_key() {
121 let key = TestKey(0);
122 let invalid_key = TestKey(1);
123 let mut store = StorageMap::<TestTable>::new();
124 let _ = store.insert(&key, &TestValue(0));
125
126 assert_eq!(store.get(&invalid_key).unwrap(), None);
127 }
128
129 #[test]
130 fn test_insert_existing_key_updates_value_for_given_key() {
131 let key = TestKey(0);
132 let mut store = StorageMap::<TestTable>::new();
133 let _ = store.insert(&key, &TestValue(0));
134 let _ = store.insert(&key, &TestValue(1));
135
136 assert_eq!(store.get(&key).unwrap(), Some(Cow::Borrowed(&TestValue(1))));
137 }
138
139 #[test]
140 fn test_remove_deletes_the_value_for_given_key() {
141 let key = TestKey(0);
142 let mut store = StorageMap::<TestTable>::new();
143 let _ = store.insert(&key, &TestValue(0));
144 let _ = store.remove(&key);
145
146 assert_eq!(store.get(&key).unwrap(), None);
147 }
148
149 #[test]
150 fn test_remove_returns_the_deleted_value_for_given_key() {
151 let key = TestKey(0);
152 let mut store = StorageMap::<TestTable>::new();
153 let _ = store.insert(&key, &TestValue(0));
154
155 assert_eq!(store.take(&key).unwrap(), Some(TestValue(0)));
156 }
157
158 #[test]
159 fn test_remove_returns_none_for_invalid_key() {
160 let invalid_key = TestKey(0);
161 let mut store = StorageMap::<TestTable>::new();
162
163 assert_eq!(store.take(&invalid_key).unwrap(), None);
164 }
165
166 #[test]
167 fn test_contains_key_returns_true_for_valid_key() {
168 let key = TestKey(0);
169 let mut store = StorageMap::<TestTable>::new();
170 let _ = store.insert(&key, &TestValue(0));
171
172 assert_eq!(store.contains_key(&key).unwrap(), true);
173 }
174
175 #[test]
176 fn test_contains_key_returns_false_for_invalid_key() {
177 let invalid_key = TestKey(0);
178 let store = StorageMap::<TestTable>::new();
179
180 assert_eq!(store.contains_key(&invalid_key).unwrap(), false);
181 }
182}