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