1use core::marker::PhantomData;
2
3use crate::{
4 abi::TypeAbiFrom,
5 codec::{
6 multi_encode_iter_or_handle_err, multi_types::MultiValue2, EncodeErrorHandler,
7 NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput,
8 },
9 types::ManagedAddress,
10};
11
12use super::{
13 source::{CurrentStorage, StorageAddress},
14 unordered_set_mapper, StorageMapper, StorageMapperFromAddress, UnorderedSetMapper,
15};
16use crate::{
17 abi::{TypeAbi, TypeDescriptionContainer, TypeName},
18 api::StorageMapperApi,
19 storage::{storage_set, StorageKey},
20 storage_clear,
21 types::{ManagedType, MultiValueEncoded},
22};
23
24const VALUE_SUFFIX: &[u8] = b"_value";
25const ID_SUFFIX: &[u8] = b"_id";
26const VALUE_TO_ID_SUFFIX: &[u8] = b"_value_to_id";
27const ID_TO_VALUE_SUFFIX: &[u8] = b"_id_to_value";
28
29type Keys<'a, SA, T, A> = unordered_set_mapper::Iter<'a, SA, T, A>;
30
31pub struct BiDiMapper<SA, K, V, A = CurrentStorage>
34where
35 SA: StorageMapperApi,
36 A: StorageAddress<SA>,
37 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
38 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
39{
40 _phantom_api: PhantomData<SA>,
41 address: A,
42 id_set_mapper: UnorderedSetMapper<SA, K, A>,
43 value_set_mapper: UnorderedSetMapper<SA, V, A>,
44 base_key: StorageKey<SA>,
45}
46
47impl<SA, K, V> StorageMapper<SA> for BiDiMapper<SA, K, V, CurrentStorage>
48where
49 SA: StorageMapperApi,
50 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
51 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
52{
53 fn new(base_key: StorageKey<SA>) -> Self {
54 let mut id_key = base_key.clone();
55 id_key.append_bytes(ID_SUFFIX);
56
57 let mut value_key = base_key.clone();
58 value_key.append_bytes(VALUE_SUFFIX);
59 BiDiMapper {
60 _phantom_api: PhantomData,
61 address: CurrentStorage,
62 id_set_mapper: UnorderedSetMapper::<SA, K>::new(id_key),
63 value_set_mapper: UnorderedSetMapper::<SA, V>::new(value_key),
64 base_key,
65 }
66 }
67}
68
69impl<SA, K, V> StorageMapperFromAddress<SA> for BiDiMapper<SA, K, V, ManagedAddress<SA>>
70where
71 SA: StorageMapperApi,
72 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
73 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
74{
75 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
76 let mut id_key = base_key.clone();
77 id_key.append_bytes(ID_SUFFIX);
78
79 let mut value_key = base_key.clone();
80 value_key.append_bytes(VALUE_SUFFIX);
81 BiDiMapper {
82 _phantom_api: PhantomData,
83 address: address.clone(),
84 id_set_mapper: UnorderedSetMapper::new_from_address(address.clone(), id_key),
85 value_set_mapper: UnorderedSetMapper::new_from_address(address, value_key),
86 base_key,
87 }
88 }
89}
90
91impl<SA, K, V, A> BiDiMapper<SA, K, V, A>
92where
93 SA: StorageMapperApi,
94 A: StorageAddress<SA>,
95 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
96 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
97{
98 fn get_id_key(&self, value: &V) -> StorageKey<SA> {
99 let mut key = self.base_key.clone();
100 key.append_bytes(VALUE_TO_ID_SUFFIX);
101 key.append_item(value);
102 key
103 }
104
105 fn get_value_key(&self, key: &K) -> StorageKey<SA> {
106 let mut value = self.base_key.clone();
107 value.append_bytes(ID_TO_VALUE_SUFFIX);
108 value.append_item(&key);
109 value
110 }
111
112 pub fn get_id(&self, value: &V) -> K {
113 self.address
114 .address_storage_get(self.get_id_key(value).as_ref())
115 }
116
117 pub fn get_value(&self, id: &K) -> V {
118 self.address
119 .address_storage_get(self.get_value_key(id).as_ref())
120 }
121
122 pub fn contains_id(&self, id: &K) -> bool {
123 self.id_set_mapper.contains(id)
124 }
125
126 pub fn contains_value(&self, value: &V) -> bool {
127 self.value_set_mapper.contains(value)
128 }
129
130 pub fn get_all_values(&self) -> unordered_set_mapper::Iter<'_, SA, V, A> {
131 self.value_set_mapper.iter()
132 }
133
134 pub fn get_all_ids(&self) -> unordered_set_mapper::Iter<'_, SA, K, A> {
135 self.id_set_mapper.iter()
136 }
137
138 pub fn iter(&self) -> Iter<'_, SA, K, V, A> {
139 Iter::new(self)
140 }
141
142 pub fn is_empty(&self) -> bool {
143 self.value_set_mapper.is_empty()
144 }
145
146 pub fn len(&self) -> usize {
147 self.value_set_mapper.len()
148 }
149}
150
151impl<SA, K, V> BiDiMapper<SA, K, V, CurrentStorage>
152where
153 SA: StorageMapperApi,
154 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
155 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
156{
157 fn set_id(&mut self, value: &V, id: &K) {
158 storage_set(self.get_id_key(value).as_ref(), id);
159 }
160
161 fn set_value(&mut self, id: &K, value: &V) {
162 storage_set(self.get_value_key(id).as_ref(), value);
163 }
164
165 fn clear_id_by_value(&self, value: &V) {
166 storage_clear(self.get_id_key(value).as_ref());
167 }
168 fn clear_value_by_id(&self, id: &K) {
169 storage_clear(self.get_value_key(id).as_ref());
170 }
171
172 pub fn insert(&mut self, id: K, value: V) -> bool {
173 if self.contains_id(&id) || self.contains_value(&value) {
174 return false;
175 }
176 self.set_id(&value, &id);
177 self.set_value(&id, &value);
178
179 self.id_set_mapper.insert(id);
180 self.value_set_mapper.insert(value);
181 true
182 }
183
184 pub fn remove_by_id(&mut self, id: &K) -> bool {
185 if self.id_set_mapper.swap_remove(id) {
186 let value = self.get_value(id);
187 self.clear_id_by_value(&value);
188 self.clear_value_by_id(id);
189 storage_clear(self.get_value_key(id).as_ref());
190 self.value_set_mapper.swap_remove(&value);
191 return true;
192 }
193 false
194 }
195 pub fn remove_by_value(&mut self, value: &V) -> bool {
196 if self.value_set_mapper.swap_remove(value) {
197 let id = self.get_id(value);
198 self.clear_id_by_value(value);
199 self.clear_value_by_id(&id);
200 self.id_set_mapper.swap_remove(&id);
201 return true;
202 }
203 false
204 }
205
206 pub fn remove_all_by_ids<I>(&mut self, iter: I)
207 where
208 I: IntoIterator<Item = K>,
209 {
210 for item in iter {
211 self.remove_by_id(&item);
212 }
213 }
214
215 pub fn remove_all_by_values<I>(&mut self, iter: I)
216 where
217 I: IntoIterator<Item = V>,
218 {
219 for item in iter {
220 self.remove_by_value(&item);
221 }
222 }
223}
224
225impl<'a, SA, K, V, A> IntoIterator for &'a BiDiMapper<SA, K, V, A>
226where
227 SA: StorageMapperApi,
228 A: StorageAddress<SA>,
229 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
230 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
231{
232 type Item = (K, V);
233
234 type IntoIter = Iter<'a, SA, K, V, A>;
235
236 fn into_iter(self) -> Self::IntoIter {
237 self.iter()
238 }
239}
240
241pub struct Iter<'a, SA, K, V, A>
242where
243 SA: StorageMapperApi,
244 A: StorageAddress<SA>,
245 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
246 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
247{
248 key_iter: Keys<'a, SA, K, A>,
249 hash_map: &'a BiDiMapper<SA, K, V, A>,
250}
251
252impl<'a, SA, K, V, A> Iter<'a, SA, K, V, A>
253where
254 SA: StorageMapperApi,
255 A: StorageAddress<SA>,
256 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
257 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
258{
259 fn new(hash_map: &'a BiDiMapper<SA, K, V, A>) -> Iter<'a, SA, K, V, A> {
260 Iter {
261 key_iter: hash_map.get_all_ids(),
262 hash_map,
263 }
264 }
265}
266
267impl<SA, K, V, A> Iterator for Iter<'_, SA, K, V, A>
268where
269 SA: StorageMapperApi,
270 A: StorageAddress<SA>,
271 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
272 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
273{
274 type Item = (K, V);
275
276 #[inline]
277 fn next(&mut self) -> Option<(K, V)> {
278 if let Some(key) = self.key_iter.next() {
279 let value = self.hash_map.get_value(&key);
280 return Some((key, value));
281 }
282 None
283 }
284}
285
286impl<SA, K, V> TopEncodeMulti for BiDiMapper<SA, K, V, CurrentStorage>
287where
288 SA: StorageMapperApi,
289 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
290 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
291{
292 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
293 where
294 O: TopEncodeMultiOutput,
295 H: EncodeErrorHandler,
296 {
297 let iter = self.iter().map(MultiValue2::<K, V>::from);
298 multi_encode_iter_or_handle_err(iter, output, h)
299 }
300}
301
302impl<SA, K, V> TypeAbiFrom<BiDiMapper<SA, K, V, CurrentStorage>>
303 for MultiValueEncoded<SA, MultiValue2<K, V>>
304where
305 SA: StorageMapperApi,
306 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
307 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
308{
309}
310
311impl<SA, K, V> TypeAbiFrom<Self> for BiDiMapper<SA, K, V, CurrentStorage>
312where
313 SA: StorageMapperApi,
314 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
315 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
316{
317}
318
319impl<SA, K, V> TypeAbi for BiDiMapper<SA, K, V, CurrentStorage>
320where
321 SA: StorageMapperApi,
322 K: TopEncode
323 + TopDecode
324 + NestedEncode
325 + NestedDecode
326 + 'static
327 + Default
328 + PartialEq
329 + TypeAbi,
330 V: TopEncode
331 + TopDecode
332 + NestedEncode
333 + NestedDecode
334 + 'static
335 + Default
336 + PartialEq
337 + TypeAbi,
338{
339 type Unmanaged = Self;
340
341 fn type_name() -> TypeName {
342 MultiValueEncoded::<SA, MultiValue2<K, V>>::type_name()
343 }
344
345 fn type_name_rust() -> TypeName {
346 MultiValueEncoded::<SA, MultiValue2<K, V>>::type_name_rust()
347 }
348
349 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
350 K::provide_type_descriptions(accumulator);
351 V::provide_type_descriptions(accumulator);
352 }
353 fn is_variadic() -> bool {
354 true
355 }
356}