multiversx_sc/storage/mappers/
unique_id_mapper.rs1use crate::{
2 abi::TypeAbiFrom,
3 codec::{
4 multi_encode_iter_or_handle_err, EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput,
5 },
6 types::ManagedAddress,
7};
8
9use super::{
10 source::{CurrentStorage, StorageAddress},
11 StorageMapper, StorageMapperFromAddress, VecMapper,
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 {
82 index
83 } else {
84 id
85 }
86 }
87
88 pub fn iter(&self) -> Iter<'_, SA, A> {
90 Iter::new(self)
91 }
92}
93
94impl<SA> UniqueIdMapper<SA, CurrentStorage>
95where
96 SA: StorageMapperApi,
97{
98 pub fn set_initial_len(&mut self, len: usize) {
100 if !self.vec_mapper.is_empty() {
101 SA::error_api_impl().signal_error(b"len already set");
102 }
103
104 self.set_internal_mapper_len(len);
105 }
106
107 pub fn swap_remove(&mut self, index: usize) -> UniqueId {
110 let last_item_index = self.len();
111 let last_item = self.get(last_item_index);
112
113 let current_item = if index != last_item_index {
114 let item_at_index = self.get(index);
115 self.set(index, last_item);
116
117 item_at_index
118 } else {
119 last_item
120 };
121
122 self.vec_mapper.set(last_item_index, &EMPTY_ENTRY);
123 self.set_internal_mapper_len(last_item_index - 1);
124
125 current_item
126 }
127
128 pub fn set(&mut self, index: usize, id: UniqueId) {
130 if index == id {
131 self.vec_mapper.set(index, &EMPTY_ENTRY);
132 } else {
133 self.vec_mapper.set(index, &id);
134 }
135 }
136
137 fn set_internal_mapper_len(&mut self, new_len: usize) {
139 let mut len_key = self.base_key.clone();
140 len_key.append_bytes(&b".len"[..]);
141 storage_set(len_key.as_ref(), &new_len);
142 }
143}
144
145impl<'a, SA, A> IntoIterator for &'a UniqueIdMapper<SA, A>
146where
147 SA: StorageMapperApi,
148 A: StorageAddress<SA>,
149{
150 type Item = usize;
151
152 type IntoIter = Iter<'a, SA, A>;
153
154 fn into_iter(self) -> Self::IntoIter {
155 self.iter()
156 }
157}
158
159pub struct Iter<'a, SA, A>
160where
161 SA: StorageMapperApi,
162 A: StorageAddress<SA>,
163{
164 index: usize,
165 len: usize,
166 id_mapper: &'a UniqueIdMapper<SA, A>,
167}
168
169impl<'a, SA, A> Iter<'a, SA, A>
170where
171 SA: StorageMapperApi,
172 A: StorageAddress<SA>,
173{
174 fn new(id_mapper: &'a UniqueIdMapper<SA, A>) -> Iter<'a, SA, A> {
175 Iter {
176 index: 1,
177 len: id_mapper.len(),
178 id_mapper,
179 }
180 }
181}
182
183impl<SA, A> Iterator for Iter<'_, SA, A>
184where
185 SA: StorageMapperApi,
186 A: StorageAddress<SA>,
187{
188 type Item = usize;
189
190 #[inline]
191 fn next(&mut self) -> Option<Self::Item> {
192 let current_index = self.index;
193 if current_index > self.len {
194 return None;
195 }
196
197 self.index += 1;
198 Some(self.id_mapper.get(current_index))
199 }
200}
201
202impl<SA> TopEncodeMulti for UniqueIdMapper<SA, CurrentStorage>
204where
205 SA: StorageMapperApi,
206{
207 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
208 where
209 O: TopEncodeMultiOutput,
210 H: EncodeErrorHandler,
211 {
212 multi_encode_iter_or_handle_err(self.iter(), output, h)
213 }
214}
215
216impl<SA> TypeAbiFrom<UniqueIdMapper<SA, CurrentStorage>> for MultiValueEncoded<SA, usize> where
217 SA: StorageMapperApi
218{
219}
220
221impl<SA> TypeAbiFrom<Self> for UniqueIdMapper<SA, CurrentStorage> where SA: StorageMapperApi {}
222
223impl<SA> TypeAbi for UniqueIdMapper<SA, CurrentStorage>
225where
226 SA: StorageMapperApi,
227{
228 type Unmanaged = Self;
229
230 fn type_name() -> TypeName {
231 crate::abi::type_name_variadic::<usize>()
232 }
233
234 fn type_name_rust() -> TypeName {
235 crate::abi::type_name_multi_value_encoded::<usize>()
236 }
237
238 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
239 usize::provide_type_descriptions(accumulator);
240 }
241
242 fn is_variadic() -> bool {
243 true
244 }
245}