1use core::marker::PhantomData;
2
3use crate::{
4 abi::TypeAbiFrom,
5 codec::{
6 EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti,
7 TopEncodeMultiOutput, multi_encode_iter_or_handle_err, multi_types::MultiValue2,
8 },
9 types::ManagedAddress,
10};
11
12use super::{
13 StorageMapper, StorageMapperFromAddress, UnorderedSetMapper,
14 source::{CurrentStorage, StorageAddress},
15 unordered_set_mapper,
16};
17use crate::{
18 abi::{TypeAbi, TypeDescriptionContainer, TypeName},
19 api::StorageMapperApi,
20 storage::{StorageKey, storage_set},
21 storage_clear,
22 types::{ManagedType, MultiValueEncoded},
23};
24
25const VALUE_SUFFIX: &[u8] = b"_value";
26const ID_SUFFIX: &[u8] = b"_id";
27const VALUE_TO_ID_SUFFIX: &[u8] = b"_value_to_id";
28const ID_TO_VALUE_SUFFIX: &[u8] = b"_id_to_value";
29
30type Keys<'a, SA, T, A> = unordered_set_mapper::Iter<'a, SA, T, A>;
31
32pub struct BiDiMapper<SA, K, V, A = CurrentStorage>
141where
142 SA: StorageMapperApi,
143 A: StorageAddress<SA>,
144 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
145 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
146{
147 _phantom_api: PhantomData<SA>,
148 address: A,
149 id_set_mapper: UnorderedSetMapper<SA, K, A>,
150 value_set_mapper: UnorderedSetMapper<SA, V, A>,
151 base_key: StorageKey<SA>,
152}
153
154impl<SA, K, V> StorageMapper<SA> for BiDiMapper<SA, K, V, CurrentStorage>
155where
156 SA: StorageMapperApi,
157 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
158 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
159{
160 fn new(base_key: StorageKey<SA>) -> Self {
161 let mut id_key = base_key.clone();
162 id_key.append_bytes(ID_SUFFIX);
163
164 let mut value_key = base_key.clone();
165 value_key.append_bytes(VALUE_SUFFIX);
166 BiDiMapper {
167 _phantom_api: PhantomData,
168 address: CurrentStorage,
169 id_set_mapper: UnorderedSetMapper::<SA, K>::new(id_key),
170 value_set_mapper: UnorderedSetMapper::<SA, V>::new(value_key),
171 base_key,
172 }
173 }
174}
175
176impl<SA, K, V> StorageMapperFromAddress<SA> for BiDiMapper<SA, K, V, ManagedAddress<SA>>
177where
178 SA: StorageMapperApi,
179 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
180 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
181{
182 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
183 let mut id_key = base_key.clone();
184 id_key.append_bytes(ID_SUFFIX);
185
186 let mut value_key = base_key.clone();
187 value_key.append_bytes(VALUE_SUFFIX);
188 BiDiMapper {
189 _phantom_api: PhantomData,
190 address: address.clone(),
191 id_set_mapper: UnorderedSetMapper::new_from_address(address.clone(), id_key),
192 value_set_mapper: UnorderedSetMapper::new_from_address(address, value_key),
193 base_key,
194 }
195 }
196}
197
198impl<SA, K, V, A> BiDiMapper<SA, K, V, A>
199where
200 SA: StorageMapperApi,
201 A: StorageAddress<SA>,
202 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
203 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
204{
205 fn get_id_key(&self, value: &V) -> StorageKey<SA> {
206 let mut key = self.base_key.clone();
207 key.append_bytes(VALUE_TO_ID_SUFFIX);
208 key.append_item(value);
209 key
210 }
211
212 fn get_value_key(&self, key: &K) -> StorageKey<SA> {
213 let mut value = self.base_key.clone();
214 value.append_bytes(ID_TO_VALUE_SUFFIX);
215 value.append_item(&key);
216 value
217 }
218
219 pub fn get_id(&self, value: &V) -> K {
220 self.address
221 .address_storage_get(self.get_id_key(value).as_ref())
222 }
223
224 pub fn get_value(&self, id: &K) -> V {
225 self.address
226 .address_storage_get(self.get_value_key(id).as_ref())
227 }
228
229 pub fn contains_id(&self, id: &K) -> bool {
230 self.id_set_mapper.contains(id)
231 }
232
233 pub fn contains_value(&self, value: &V) -> bool {
234 self.value_set_mapper.contains(value)
235 }
236
237 pub fn get_all_values(&self) -> unordered_set_mapper::Iter<'_, SA, V, A> {
238 self.value_set_mapper.iter()
239 }
240
241 pub fn get_all_ids(&self) -> unordered_set_mapper::Iter<'_, SA, K, A> {
242 self.id_set_mapper.iter()
243 }
244
245 pub fn iter(&self) -> Iter<'_, SA, K, V, A> {
246 Iter::new(self)
247 }
248
249 pub fn is_empty(&self) -> bool {
250 self.value_set_mapper.is_empty()
251 }
252
253 pub fn len(&self) -> usize {
254 self.value_set_mapper.len()
255 }
256}
257
258impl<SA, K, V> BiDiMapper<SA, K, V, CurrentStorage>
259where
260 SA: StorageMapperApi,
261 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
262 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
263{
264 fn set_id(&mut self, value: &V, id: &K) {
265 storage_set(self.get_id_key(value).as_ref(), id);
266 }
267
268 fn set_value(&mut self, id: &K, value: &V) {
269 storage_set(self.get_value_key(id).as_ref(), value);
270 }
271
272 fn clear_id_by_value(&self, value: &V) {
273 storage_clear(self.get_id_key(value).as_ref());
274 }
275 fn clear_value_by_id(&self, id: &K) {
276 storage_clear(self.get_value_key(id).as_ref());
277 }
278
279 pub fn insert(&mut self, id: K, value: V) -> bool {
280 if self.contains_id(&id) || self.contains_value(&value) {
281 return false;
282 }
283 self.set_id(&value, &id);
284 self.set_value(&id, &value);
285
286 self.id_set_mapper.insert(id);
287 self.value_set_mapper.insert(value);
288 true
289 }
290
291 pub fn remove_by_id(&mut self, id: &K) -> bool {
292 if self.id_set_mapper.swap_remove(id) {
293 let value = self.get_value(id);
294 self.clear_id_by_value(&value);
295 self.clear_value_by_id(id);
296 storage_clear(self.get_value_key(id).as_ref());
297 self.value_set_mapper.swap_remove(&value);
298 return true;
299 }
300 false
301 }
302 pub fn remove_by_value(&mut self, value: &V) -> bool {
303 if self.value_set_mapper.swap_remove(value) {
304 let id = self.get_id(value);
305 self.clear_id_by_value(value);
306 self.clear_value_by_id(&id);
307 self.id_set_mapper.swap_remove(&id);
308 return true;
309 }
310 false
311 }
312
313 pub fn remove_all_by_ids<I>(&mut self, iter: I)
314 where
315 I: IntoIterator<Item = K>,
316 {
317 for item in iter {
318 self.remove_by_id(&item);
319 }
320 }
321
322 pub fn remove_all_by_values<I>(&mut self, iter: I)
323 where
324 I: IntoIterator<Item = V>,
325 {
326 for item in iter {
327 self.remove_by_value(&item);
328 }
329 }
330}
331
332impl<'a, SA, K, V, A> IntoIterator for &'a BiDiMapper<SA, K, V, A>
333where
334 SA: StorageMapperApi,
335 A: StorageAddress<SA>,
336 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
337 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
338{
339 type Item = (K, V);
340
341 type IntoIter = Iter<'a, SA, K, V, A>;
342
343 fn into_iter(self) -> Self::IntoIter {
344 self.iter()
345 }
346}
347
348pub struct Iter<'a, SA, K, V, A>
349where
350 SA: StorageMapperApi,
351 A: StorageAddress<SA>,
352 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
353 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
354{
355 key_iter: Keys<'a, SA, K, A>,
356 hash_map: &'a BiDiMapper<SA, K, V, A>,
357}
358
359impl<'a, SA, K, V, A> Iter<'a, SA, K, V, A>
360where
361 SA: StorageMapperApi,
362 A: StorageAddress<SA>,
363 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
364 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
365{
366 fn new(hash_map: &'a BiDiMapper<SA, K, V, A>) -> Iter<'a, SA, K, V, A> {
367 Iter {
368 key_iter: hash_map.get_all_ids(),
369 hash_map,
370 }
371 }
372}
373
374impl<SA, K, V, A> Iterator for Iter<'_, SA, K, V, A>
375where
376 SA: StorageMapperApi,
377 A: StorageAddress<SA>,
378 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
379 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
380{
381 type Item = (K, V);
382
383 #[inline]
384 fn next(&mut self) -> Option<(K, V)> {
385 if let Some(key) = self.key_iter.next() {
386 let value = self.hash_map.get_value(&key);
387 return Some((key, value));
388 }
389 None
390 }
391}
392
393impl<SA, K, V> TopEncodeMulti for BiDiMapper<SA, K, V, CurrentStorage>
394where
395 SA: StorageMapperApi,
396 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
397 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
398{
399 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
400 where
401 O: TopEncodeMultiOutput,
402 H: EncodeErrorHandler,
403 {
404 let iter = self.iter().map(MultiValue2::<K, V>::from);
405 multi_encode_iter_or_handle_err(iter, output, h)
406 }
407}
408
409impl<SA, K, V> TypeAbiFrom<BiDiMapper<SA, K, V, CurrentStorage>>
410 for MultiValueEncoded<SA, MultiValue2<K, V>>
411where
412 SA: StorageMapperApi,
413 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
414 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
415{
416}
417
418impl<SA, K, V> TypeAbiFrom<Self> for BiDiMapper<SA, K, V, CurrentStorage>
419where
420 SA: StorageMapperApi,
421 K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
422 V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq,
423{
424}
425
426impl<SA, K, V> TypeAbi for BiDiMapper<SA, K, V, CurrentStorage>
427where
428 SA: StorageMapperApi,
429 K: TopEncode
430 + TopDecode
431 + NestedEncode
432 + NestedDecode
433 + 'static
434 + Default
435 + PartialEq
436 + TypeAbi,
437 V: TopEncode
438 + TopDecode
439 + NestedEncode
440 + NestedDecode
441 + 'static
442 + Default
443 + PartialEq
444 + TypeAbi,
445{
446 type Unmanaged = Self;
447
448 fn type_name() -> TypeName {
449 MultiValueEncoded::<SA, MultiValue2<K, V>>::type_name()
450 }
451
452 fn type_name_rust() -> TypeName {
453 MultiValueEncoded::<SA, MultiValue2<K, V>>::type_name_rust()
454 }
455
456 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
457 K::provide_type_descriptions(accumulator);
458 V::provide_type_descriptions(accumulator);
459 }
460 fn is_variadic() -> bool {
461 true
462 }
463}