multiversx_sc/storage/mappers/
unique_id_mapper.rs1use crate::{
2 abi::TypeAbiFrom,
3 codec::{
4 EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput, multi_encode_iter_or_handle_err,
5 },
6 types::ManagedAddress,
7};
8
9use super::{
10 StorageMapper, StorageMapperFromAddress, VecMapper,
11 source::{CurrentStorage, StorageAddress},
12};
13use crate::{
14 abi::{TypeAbi, TypeDescriptionContainer, TypeName},
15 api::{ErrorApiImpl, StorageMapperApi},
16 storage::StorageKey,
17 storage_set,
18 types::{ManagedType, MultiValueEncoded},
19};
20
21pub type UniqueId = usize;
22const EMPTY_ENTRY: UniqueId = 0;
23
24pub struct UniqueIdMapper<SA, A = CurrentStorage>
28where
29 SA: StorageMapperApi,
30 A: StorageAddress<SA>,
31{
32 _address: A,
33 base_key: StorageKey<SA>,
34 vec_mapper: VecMapper<SA, UniqueId, A>,
35}
36
37impl<SA> StorageMapper<SA> for UniqueIdMapper<SA, CurrentStorage>
38where
39 SA: StorageMapperApi,
40{
41 fn new(base_key: StorageKey<SA>) -> Self {
42 Self {
43 _address: CurrentStorage,
44 base_key: base_key.clone(),
45 vec_mapper: VecMapper::new(base_key),
46 }
47 }
48}
49
50impl<SA> StorageMapperFromAddress<SA> for UniqueIdMapper<SA, ManagedAddress<SA>>
51where
52 SA: StorageMapperApi,
53{
54 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
55 Self {
56 _address: address.clone(),
57 base_key: base_key.clone(),
58 vec_mapper: VecMapper::new_from_address(address, base_key),
59 }
60 }
61}
62
63impl<SA, A> UniqueIdMapper<SA, A>
64where
65 SA: StorageMapperApi,
66 A: StorageAddress<SA>,
67{
68 #[inline]
69 pub fn len(&self) -> usize {
70 self.vec_mapper.len()
71 }
72
73 #[inline]
74 pub fn is_empty(&self) -> bool {
75 self.vec_mapper.is_empty()
76 }
77
78 pub fn get(&self, index: usize) -> UniqueId {
80 let id: UniqueId = self.vec_mapper.get(index);
81 if id == EMPTY_ENTRY { index } else { id }
82 }
83
84 pub fn iter(&self) -> Iter<'_, SA, A> {
86 Iter::new(self)
87 }
88}
89
90impl<SA> UniqueIdMapper<SA, CurrentStorage>
91where
92 SA: StorageMapperApi,
93{
94 pub fn set_initial_len(&mut self, len: usize) {
96 if !self.vec_mapper.is_empty() {
97 SA::error_api_impl().signal_error(b"len already set");
98 }
99
100 self.set_internal_mapper_len(len);
101 }
102
103 pub fn swap_remove(&mut self, index: usize) -> UniqueId {
106 let last_item_index = self.len();
107 let last_item = self.get(last_item_index);
108
109 let current_item = if index != last_item_index {
110 let item_at_index = self.get(index);
111 self.set(index, last_item);
112
113 item_at_index
114 } else {
115 last_item
116 };
117
118 self.vec_mapper.set(last_item_index, &EMPTY_ENTRY);
119 self.set_internal_mapper_len(last_item_index - 1);
120
121 current_item
122 }
123
124 pub fn set(&mut self, index: usize, id: UniqueId) {
126 if index == id {
127 self.vec_mapper.set(index, &EMPTY_ENTRY);
128 } else {
129 self.vec_mapper.set(index, &id);
130 }
131 }
132
133 fn set_internal_mapper_len(&mut self, new_len: usize) {
135 let mut len_key = self.base_key.clone();
136 len_key.append_bytes(&b".len"[..]);
137 storage_set(len_key.as_ref(), &new_len);
138 }
139}
140
141impl<'a, SA, A> IntoIterator for &'a UniqueIdMapper<SA, A>
142where
143 SA: StorageMapperApi,
144 A: StorageAddress<SA>,
145{
146 type Item = usize;
147
148 type IntoIter = Iter<'a, SA, A>;
149
150 fn into_iter(self) -> Self::IntoIter {
151 self.iter()
152 }
153}
154
155pub struct Iter<'a, SA, A>
156where
157 SA: StorageMapperApi,
158 A: StorageAddress<SA>,
159{
160 index: usize,
161 len: usize,
162 id_mapper: &'a UniqueIdMapper<SA, A>,
163}
164
165impl<'a, SA, A> Iter<'a, SA, A>
166where
167 SA: StorageMapperApi,
168 A: StorageAddress<SA>,
169{
170 fn new(id_mapper: &'a UniqueIdMapper<SA, A>) -> Iter<'a, SA, A> {
171 Iter {
172 index: 1,
173 len: id_mapper.len(),
174 id_mapper,
175 }
176 }
177}
178
179impl<SA, A> Iterator for Iter<'_, SA, A>
180where
181 SA: StorageMapperApi,
182 A: StorageAddress<SA>,
183{
184 type Item = usize;
185
186 #[inline]
187 fn next(&mut self) -> Option<Self::Item> {
188 let current_index = self.index;
189 if current_index > self.len {
190 return None;
191 }
192
193 self.index += 1;
194 Some(self.id_mapper.get(current_index))
195 }
196}
197
198impl<SA> TopEncodeMulti for UniqueIdMapper<SA, CurrentStorage>
200where
201 SA: StorageMapperApi,
202{
203 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
204 where
205 O: TopEncodeMultiOutput,
206 H: EncodeErrorHandler,
207 {
208 multi_encode_iter_or_handle_err(self.iter(), output, h)
209 }
210}
211
212impl<SA> TypeAbiFrom<UniqueIdMapper<SA, CurrentStorage>> for MultiValueEncoded<SA, usize> where
213 SA: StorageMapperApi
214{
215}
216
217impl<SA> TypeAbiFrom<Self> for UniqueIdMapper<SA, CurrentStorage> where SA: StorageMapperApi {}
218
219impl<SA> TypeAbi for UniqueIdMapper<SA, CurrentStorage>
221where
222 SA: StorageMapperApi,
223{
224 type Unmanaged = Self;
225
226 fn type_name() -> TypeName {
227 crate::abi::type_name_variadic::<usize>()
228 }
229
230 fn type_name_rust() -> TypeName {
231 crate::abi::type_name_multi_value_encoded::<usize>()
232 }
233
234 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
235 usize::provide_type_descriptions(accumulator);
236 }
237
238 fn is_variadic() -> bool {
239 true
240 }
241}