multiversx_sc/storage/mappers/
unordered_set_mapper.rs1use core::marker::PhantomData;
2
3pub use super::vec_mapper::Iter;
4use super::{
5 StorageClearable, StorageMapper, StorageMapperFromAddress, VecMapper,
6 source::{CurrentStorage, StorageAddress},
7};
8use crate::{
9 abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
10 api::StorageMapperApi,
11 codec::{
12 EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti,
13 TopEncodeMultiOutput, multi_encode_iter_or_handle_err,
14 },
15 storage::StorageKey,
16 storage_clear, storage_set,
17 types::{ManagedAddress, ManagedType, MultiValueEncoded},
18};
19
20const ITEM_INDEX: &[u8] = b".index";
21const NULL_ENTRY: usize = 0;
22
23pub struct UnorderedSetMapper<SA, T, A = CurrentStorage>
71where
72 SA: StorageMapperApi,
73 A: StorageAddress<SA>,
74 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
75{
76 _phantom_api: PhantomData<SA>,
77 address: A,
78 base_key: StorageKey<SA>,
79 vec_mapper: VecMapper<SA, T, A>,
80}
81
82impl<SA, T> StorageMapper<SA> for UnorderedSetMapper<SA, T, CurrentStorage>
83where
84 SA: StorageMapperApi,
85 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
86{
87 fn new(base_key: StorageKey<SA>) -> Self {
88 UnorderedSetMapper {
89 _phantom_api: PhantomData,
90 address: CurrentStorage,
91 base_key: base_key.clone(),
92 vec_mapper: VecMapper::<SA, T>::new(base_key),
93 }
94 }
95}
96
97impl<SA, T> StorageMapperFromAddress<SA> for UnorderedSetMapper<SA, T, ManagedAddress<SA>>
98where
99 SA: StorageMapperApi,
100 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
101{
102 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
103 UnorderedSetMapper {
104 _phantom_api: PhantomData,
105 address: address.clone(),
106 base_key: base_key.clone(),
107 vec_mapper: VecMapper::new_from_address(address, base_key),
108 }
109 }
110}
111
112impl<SA, T> StorageClearable for UnorderedSetMapper<SA, T, CurrentStorage>
113where
114 SA: StorageMapperApi,
115 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
116{
117 fn clear(&mut self) {
118 for value in self.vec_mapper.iter() {
119 self.clear_index(&value);
120 }
121 self.vec_mapper.clear();
122 }
123}
124
125impl<SA, T, A> UnorderedSetMapper<SA, T, A>
126where
127 SA: StorageMapperApi,
128 A: StorageAddress<SA>,
129 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
130{
131 fn item_index_key(&self, value: &T) -> StorageKey<SA> {
132 let mut item_key = self.base_key.clone();
133 item_key.append_bytes(ITEM_INDEX);
134 item_key.append_item(value);
135 item_key
136 }
137
138 pub fn get_index(&self, value: &T) -> usize {
141 self.address
142 .address_storage_get(self.item_index_key(value).as_ref())
143 }
144
145 pub fn get_by_index(&self, index: usize) -> T {
148 self.vec_mapper.get(index)
149 }
150
151 pub fn is_empty(&self) -> bool {
153 self.vec_mapper.is_empty()
154 }
155
156 pub fn len(&self) -> usize {
158 self.vec_mapper.len()
159 }
160
161 pub fn contains(&self, value: &T) -> bool {
163 self.get_index(value) != NULL_ENTRY
164 }
165
166 pub fn iter(&self) -> Iter<'_, SA, T, A> {
169 self.vec_mapper.iter()
170 }
171}
172
173impl<SA, T> UnorderedSetMapper<SA, T, CurrentStorage>
174where
175 SA: StorageMapperApi,
176 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
177{
178 fn set_index(&self, value: &T, index: usize) {
179 storage_set(self.item_index_key(value).as_ref(), &index);
180 }
181
182 fn clear_index(&self, value: &T) {
183 storage_clear(self.item_index_key(value).as_ref());
184 }
185
186 pub fn insert(&mut self, value: T) -> bool {
192 if self.contains(&value) {
193 return false;
194 }
195 self.vec_mapper.push(&value);
196 self.set_index(&value, self.len());
197 true
198 }
199
200 pub fn swap_remove(&mut self, value: &T) -> bool {
203 let index = self.get_index(value);
204 if index == NULL_ENTRY {
205 return false;
206 }
207 if let Some(last_item) = self.vec_mapper.swap_remove_and_get_old_last(index) {
208 self.set_index(&last_item, index);
209 }
210 self.clear_index(value);
211 true
212 }
213
214 pub fn swap_indexes(&mut self, index1: usize, index2: usize) -> bool {
217 if index1 == NULL_ENTRY || index2 == NULL_ENTRY {
218 return false;
219 }
220 let value1 = self.get_by_index(index1);
221 let value2 = self.get_by_index(index2);
222 self.vec_mapper.set(index2, &value1);
223 self.vec_mapper.set(index1, &value2);
224 self.set_index(&value1, index2);
225 self.set_index(&value2, index1);
226 true
227 }
228}
229
230impl<'a, SA, T, A> IntoIterator for &'a UnorderedSetMapper<SA, T, A>
231where
232 SA: StorageMapperApi,
233 A: StorageAddress<SA>,
234 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
235{
236 type Item = T;
237
238 type IntoIter = Iter<'a, SA, T, A>;
239
240 fn into_iter(self) -> Self::IntoIter {
241 self.iter()
242 }
243}
244
245impl<SA, T> Extend<T> for UnorderedSetMapper<SA, T>
246where
247 SA: StorageMapperApi,
248 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
249{
250 fn extend<I>(&mut self, iter: I)
251 where
252 I: IntoIterator<Item = T>,
253 {
254 for item in iter {
255 self.insert(item);
256 }
257 }
258}
259
260impl<SA, T> TopEncodeMulti for UnorderedSetMapper<SA, T>
262where
263 SA: StorageMapperApi,
264 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
265{
266 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
267 where
268 O: TopEncodeMultiOutput,
269 H: EncodeErrorHandler,
270 {
271 multi_encode_iter_or_handle_err(self.iter(), output, h)
272 }
273}
274
275impl<SA, T> TypeAbiFrom<UnorderedSetMapper<SA, T>> for MultiValueEncoded<SA, T>
276where
277 SA: StorageMapperApi,
278 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
279{
280}
281
282impl<SA, T> TypeAbiFrom<Self> for UnorderedSetMapper<SA, T>
283where
284 SA: StorageMapperApi,
285 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
286{
287}
288
289impl<SA, T> TypeAbi for UnorderedSetMapper<SA, T>
291where
292 SA: StorageMapperApi,
293 T: TopEncode + TopDecode + NestedEncode + NestedDecode + TypeAbi,
294{
295 type Unmanaged = Self;
296
297 fn type_name() -> TypeName {
298 crate::abi::type_name_variadic::<T>()
299 }
300
301 fn type_name_rust() -> TypeName {
302 crate::abi::type_name_multi_value_encoded::<T>()
303 }
304
305 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
306 T::provide_type_descriptions(accumulator);
307 }
308
309 fn is_variadic() -> bool {
310 true
311 }
312}