1use super::{
2 StorageClearable, StorageMapper, StorageMapperFromAddress,
3 source::{CurrentStorage, StorageAddress},
4};
5use crate::{
6 abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
7 api::{ErrorApiImpl, StorageMapperApi},
8 codec::{
9 EncodeErrorHandler, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput,
10 multi_encode_iter_or_handle_err,
11 },
12 storage::{StorageKey, storage_clear, storage_set},
13 types::{ManagedAddress, ManagedType, MultiValueEncoded},
14};
15use core::marker::PhantomData;
16
17const LEN_SUFFIX: &str = ".len";
18const ITEM_SUFFIX: &str = ".item";
19
20const INDEX_OUT_OF_RANGE_ERR_MSG: &str = "index out of range";
21
22pub struct VecMapper<SA, T, A = CurrentStorage>
74where
75 SA: StorageMapperApi,
76 T: TopEncode + TopDecode + 'static,
77{
78 _phantom_api: PhantomData<SA>,
79 address: A,
80 base_key: StorageKey<SA>,
81 len_key: StorageKey<SA>,
82 _phantom_item: PhantomData<T>,
83}
84
85impl<SA, T> StorageMapper<SA> for VecMapper<SA, T, CurrentStorage>
86where
87 SA: StorageMapperApi,
88 T: TopEncode + TopDecode,
89{
90 fn new(base_key: StorageKey<SA>) -> Self {
91 let mut len_key = base_key.clone();
92 len_key.append_bytes(LEN_SUFFIX.as_bytes());
93
94 VecMapper {
95 _phantom_api: PhantomData,
96 address: CurrentStorage,
97 base_key,
98 len_key,
99 _phantom_item: PhantomData,
100 }
101 }
102}
103
104impl<SA, T> StorageMapperFromAddress<SA> for VecMapper<SA, T, ManagedAddress<SA>>
105where
106 SA: StorageMapperApi,
107 T: TopEncode + TopDecode,
108{
109 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
110 let mut len_key = base_key.clone();
111 len_key.append_bytes(LEN_SUFFIX.as_bytes());
112
113 VecMapper {
114 _phantom_api: PhantomData,
115 address,
116 base_key,
117 len_key,
118 _phantom_item: PhantomData,
119 }
120 }
121}
122
123impl<SA, T> StorageClearable for VecMapper<SA, T, CurrentStorage>
124where
125 SA: StorageMapperApi,
126 T: TopEncode + TopDecode,
127{
128 fn clear(&mut self) {
129 self.clear();
130 }
131}
132
133impl<SA, T, A> VecMapper<SA, T, A>
134where
135 SA: StorageMapperApi,
136 A: StorageAddress<SA>,
137 T: TopEncode + TopDecode,
138{
139 fn item_key(&self, index: usize) -> StorageKey<SA> {
140 let mut item_key = self.base_key.clone();
141 item_key.append_bytes(ITEM_SUFFIX.as_bytes());
142 item_key.append_item(&index);
143 item_key
144 }
145
146 pub fn len(&self) -> usize {
148 self.address.address_storage_get(self.len_key.as_ref())
149 }
150
151 pub fn is_empty(&self) -> bool {
153 self.len() == 0
154 }
155
156 pub fn get(&self, index: usize) -> T {
159 if index == 0 || index > self.len() {
160 SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG.as_bytes());
161 }
162 self.get_unchecked(index)
163 }
164
165 pub fn get_unchecked(&self, index: usize) -> T {
169 self.address
170 .address_storage_get(self.item_key(index).as_ref())
171 }
172
173 pub fn get_or_else<F: FnOnce() -> T>(self, index: usize, or_else: F) -> T {
178 if index == 0 || index > self.len() {
179 or_else()
180 } else {
181 self.get_unchecked(index)
182 }
183 }
184
185 pub fn item_is_empty(&self, index: usize) -> bool {
188 if index == 0 || index > self.len() {
189 SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG.as_bytes());
190 }
191 self.item_is_empty_unchecked(index)
192 }
193
194 pub fn item_is_empty_unchecked(&self, index: usize) -> bool {
198 self.address
199 .address_storage_get_len(self.item_key(index).as_ref())
200 == 0
201 }
202
203 #[cfg(feature = "alloc")]
206 pub fn load_as_vec(&self) -> alloc::vec::Vec<T> {
207 self.iter().collect()
208 }
209
210 pub fn iter(&self) -> Iter<'_, SA, T, A> {
212 Iter::new(self)
213 }
214}
215
216impl<SA, T> VecMapper<SA, T, CurrentStorage>
217where
218 SA: StorageMapperApi,
219 T: TopEncode + TopDecode,
220{
221 fn save_count(&self, new_len: usize) {
222 storage_set(self.len_key.as_ref(), &new_len);
223 }
224
225 pub fn push(&mut self, item: &T) -> usize {
228 let mut len = self.len();
229 len += 1;
230 storage_set(self.item_key(len).as_ref(), item);
231 self.save_count(len);
232 len
233 }
234
235 pub fn extend_from_slice(&mut self, items: &[T]) -> usize {
239 let mut len = self.len();
240 for item in items {
241 len += 1;
242 storage_set(self.item_key(len).as_ref(), item);
243 }
244 self.save_count(len);
245 len
246 }
247
248 pub fn set(&mut self, index: usize, item: &T) {
251 if index == 0 || index > self.len() {
252 SA::error_api_impl().signal_error(&b"index out of range"[..]);
253 }
254 self.set_unchecked(index, item);
255 }
256
257 pub fn update<R, F: FnOnce(&mut T) -> R>(&mut self, index: usize, f: F) -> R {
261 let mut value = self.get(index);
262 let result = f(&mut value);
263 self.set(index, &value);
264 result
265 }
266
267 fn set_unchecked(&self, index: usize, item: &T) {
269 storage_set(self.item_key(index).as_ref(), item);
270 }
271
272 pub fn clear_entry(&self, index: usize) {
275 if index == 0 || index > self.len() {
276 SA::error_api_impl().signal_error(&b"index out of range"[..]);
277 }
278 self.clear_entry_unchecked(index)
279 }
280
281 pub fn clear_entry_unchecked(&self, index: usize) {
285 storage_clear(self.item_key(index).as_ref());
286 }
287
288 pub fn swap_remove(&mut self, index: usize) {
292 let _ = self.swap_remove_and_get_old_last(index);
293 }
294
295 pub(crate) fn swap_remove_and_get_old_last(&mut self, index: usize) -> Option<T> {
296 let last_item_index = self.len();
297 if index == 0 || index > last_item_index {
298 SA::error_api_impl().signal_error(&b"index out of range"[..]);
299 }
300
301 let mut last_item_as_option = Option::None;
302 if index != last_item_index {
303 let last_item = self.get(last_item_index);
304 self.set(index, &last_item);
305 last_item_as_option = Some(last_item);
306 }
307 self.clear_entry(last_item_index);
308 self.save_count(last_item_index - 1);
309 last_item_as_option
310 }
311
312 pub fn clear(&mut self) {
315 let len = self.len();
316 for i in 1..=len {
317 storage_clear(self.item_key(i).as_ref());
318 }
319 self.save_count(0);
320 }
321}
322
323impl<'a, SA, T, A> IntoIterator for &'a VecMapper<SA, T, A>
324where
325 SA: StorageMapperApi,
326 A: StorageAddress<SA>,
327 T: TopEncode + TopDecode + 'static,
328{
329 type Item = T;
330
331 type IntoIter = Iter<'a, SA, T, A>;
332
333 fn into_iter(self) -> Self::IntoIter {
334 self.iter()
335 }
336}
337
338pub struct Iter<'a, SA, T, A>
343where
344 SA: StorageMapperApi,
345 A: StorageAddress<SA>,
346 T: TopEncode + TopDecode + 'static,
347{
348 index: usize,
349 len: usize,
350 vec: &'a VecMapper<SA, T, A>,
351}
352
353impl<'a, SA, T, A> Iter<'a, SA, T, A>
354where
355 SA: StorageMapperApi,
356 A: StorageAddress<SA>,
357 T: TopEncode + TopDecode + 'static,
358{
359 fn new(vec: &'a VecMapper<SA, T, A>) -> Iter<'a, SA, T, A> {
360 Iter {
361 index: 1,
362 len: vec.len(),
363 vec,
364 }
365 }
366}
367
368impl<SA, T, A> Iterator for Iter<'_, SA, T, A>
369where
370 SA: StorageMapperApi,
371 A: StorageAddress<SA>,
372 T: TopEncode + TopDecode + 'static,
373{
374 type Item = T;
375
376 #[inline]
377 fn next(&mut self) -> Option<T> {
378 let current_index = self.index;
379 if current_index > self.len {
380 return None;
381 }
382 self.index += 1;
383 Some(self.vec.get_unchecked(current_index))
384 }
385}
386
387impl<SA, T> TopEncodeMulti for VecMapper<SA, T, CurrentStorage>
389where
390 SA: StorageMapperApi,
391 T: TopEncode + TopDecode,
392{
393 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
394 where
395 O: TopEncodeMultiOutput,
396 H: EncodeErrorHandler,
397 {
398 multi_encode_iter_or_handle_err(self.iter(), output, h)
399 }
400}
401
402impl<SA, T> TypeAbiFrom<VecMapper<SA, T, CurrentStorage>> for MultiValueEncoded<SA, T>
403where
404 SA: StorageMapperApi,
405 T: TopEncode + TopDecode,
406{
407}
408
409impl<SA, T> TypeAbiFrom<Self> for VecMapper<SA, T, CurrentStorage>
410where
411 SA: StorageMapperApi,
412 T: TopEncode + TopDecode,
413{
414}
415
416impl<SA, T> TypeAbi for VecMapper<SA, T, CurrentStorage>
418where
419 SA: StorageMapperApi,
420 T: TopEncode + TopDecode + TypeAbi,
421{
422 type Unmanaged = Self;
423
424 fn type_name() -> TypeName {
425 crate::abi::type_name_variadic::<T>()
426 }
427
428 fn type_name_rust() -> TypeName {
429 crate::abi::type_name_multi_value_encoded::<T>()
430 }
431
432 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
433 T::provide_type_descriptions(accumulator);
434 }
435
436 fn is_variadic() -> bool {
437 true
438 }
439}