multiversx_sc/storage/mappers/
unordered_set_mapper.rs1use core::marker::PhantomData;
2
3pub use super::vec_mapper::Iter;
4use super::{
5 source::{CurrentStorage, StorageAddress},
6 StorageClearable, StorageMapper, StorageMapperFromAddress, VecMapper,
7};
8use crate::{
9 abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
10 api::StorageMapperApi,
11 codec::{
12 multi_encode_iter_or_handle_err, EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode,
13 TopEncode, TopEncodeMulti, TopEncodeMultiOutput,
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>
24where
25 SA: StorageMapperApi,
26 A: StorageAddress<SA>,
27 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
28{
29 _phantom_api: PhantomData<SA>,
30 address: A,
31 base_key: StorageKey<SA>,
32 vec_mapper: VecMapper<SA, T, A>,
33}
34
35impl<SA, T> StorageMapper<SA> for UnorderedSetMapper<SA, T, CurrentStorage>
36where
37 SA: StorageMapperApi,
38 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
39{
40 fn new(base_key: StorageKey<SA>) -> Self {
41 UnorderedSetMapper {
42 _phantom_api: PhantomData,
43 address: CurrentStorage,
44 base_key: base_key.clone(),
45 vec_mapper: VecMapper::<SA, T>::new(base_key),
46 }
47 }
48}
49
50impl<SA, T> StorageMapperFromAddress<SA> for UnorderedSetMapper<SA, T, ManagedAddress<SA>>
51where
52 SA: StorageMapperApi,
53 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
54{
55 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
56 UnorderedSetMapper {
57 _phantom_api: PhantomData,
58 address: address.clone(),
59 base_key: base_key.clone(),
60 vec_mapper: VecMapper::new_from_address(address, base_key),
61 }
62 }
63}
64
65impl<SA, T> StorageClearable for UnorderedSetMapper<SA, T, CurrentStorage>
66where
67 SA: StorageMapperApi,
68 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
69{
70 fn clear(&mut self) {
71 for value in self.vec_mapper.iter() {
72 self.clear_index(&value);
73 }
74 self.vec_mapper.clear();
75 }
76}
77
78impl<SA, T, A> UnorderedSetMapper<SA, T, A>
79where
80 SA: StorageMapperApi,
81 A: StorageAddress<SA>,
82 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
83{
84 fn item_index_key(&self, value: &T) -> StorageKey<SA> {
85 let mut item_key = self.base_key.clone();
86 item_key.append_bytes(ITEM_INDEX);
87 item_key.append_item(value);
88 item_key
89 }
90
91 pub fn get_index(&self, value: &T) -> usize {
94 self.address
95 .address_storage_get(self.item_index_key(value).as_ref())
96 }
97
98 pub fn get_by_index(&self, index: usize) -> T {
101 self.vec_mapper.get(index)
102 }
103
104 pub fn is_empty(&self) -> bool {
106 self.vec_mapper.is_empty()
107 }
108
109 pub fn len(&self) -> usize {
111 self.vec_mapper.len()
112 }
113
114 pub fn contains(&self, value: &T) -> bool {
116 self.get_index(value) != NULL_ENTRY
117 }
118
119 pub fn iter(&self) -> Iter<'_, SA, T, A> {
122 self.vec_mapper.iter()
123 }
124}
125
126impl<SA, T> UnorderedSetMapper<SA, T, CurrentStorage>
127where
128 SA: StorageMapperApi,
129 T: TopEncode + TopDecode + NestedEncode + NestedDecode,
130{
131 fn set_index(&self, value: &T, index: usize) {
132 storage_set(self.item_index_key(value).as_ref(), &index);
133 }
134
135 fn clear_index(&self, value: &T) {
136 storage_clear(self.item_index_key(value).as_ref());
137 }
138
139 pub fn insert(&mut self, value: T) -> bool {
145 if self.contains(&value) {
146 return false;
147 }
148 self.vec_mapper.push(&value);
149 self.set_index(&value, self.len());
150 true
151 }
152
153 pub fn swap_remove(&mut self, value: &T) -> bool {
156 let index = self.get_index(value);
157 if index == NULL_ENTRY {
158 return false;
159 }
160 if let Some(last_item) = self.vec_mapper.swap_remove_and_get_old_last(index) {
161 self.set_index(&last_item, index);
162 }
163 self.clear_index(value);
164 true
165 }
166
167 pub fn swap_indexes(&mut self, index1: usize, index2: usize) -> bool {
170 if index1 == NULL_ENTRY || index2 == NULL_ENTRY {
171 return false;
172 }
173 let value1 = self.get_by_index(index1);
174 let value2 = self.get_by_index(index2);
175 self.vec_mapper.set(index2, &value1);
176 self.vec_mapper.set(index1, &value2);
177 self.set_index(&value1, index2);
178 self.set_index(&value2, index1);
179 true
180 }
181}
182
183impl<'a, SA, T, A> IntoIterator for &'a UnorderedSetMapper<SA, T, A>
184where
185 SA: StorageMapperApi,
186 A: StorageAddress<SA>,
187 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
188{
189 type Item = T;
190
191 type IntoIter = Iter<'a, SA, T, A>;
192
193 fn into_iter(self) -> Self::IntoIter {
194 self.iter()
195 }
196}
197
198impl<SA, T> Extend<T> for UnorderedSetMapper<SA, T>
199where
200 SA: StorageMapperApi,
201 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
202{
203 fn extend<I>(&mut self, iter: I)
204 where
205 I: IntoIterator<Item = T>,
206 {
207 for item in iter {
208 self.insert(item);
209 }
210 }
211}
212
213impl<SA, T> TopEncodeMulti for UnorderedSetMapper<SA, T>
215where
216 SA: StorageMapperApi,
217 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
218{
219 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
220 where
221 O: TopEncodeMultiOutput,
222 H: EncodeErrorHandler,
223 {
224 multi_encode_iter_or_handle_err(self.iter(), output, h)
225 }
226}
227
228impl<SA, T> TypeAbiFrom<UnorderedSetMapper<SA, T>> for MultiValueEncoded<SA, T>
229where
230 SA: StorageMapperApi,
231 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
232{
233}
234
235impl<SA, T> TypeAbiFrom<Self> for UnorderedSetMapper<SA, T>
236where
237 SA: StorageMapperApi,
238 T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static,
239{
240}
241
242impl<SA, T> TypeAbi for UnorderedSetMapper<SA, T>
244where
245 SA: StorageMapperApi,
246 T: TopEncode + TopDecode + NestedEncode + NestedDecode + TypeAbi,
247{
248 type Unmanaged = Self;
249
250 fn type_name() -> TypeName {
251 crate::abi::type_name_variadic::<T>()
252 }
253
254 fn type_name_rust() -> TypeName {
255 crate::abi::type_name_multi_value_encoded::<T>()
256 }
257
258 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
259 T::provide_type_descriptions(accumulator);
260 }
261
262 fn is_variadic() -> bool {
263 true
264 }
265}