1use super::{
2 source::{CurrentStorage, StorageAddress},
3 StorageClearable, StorageMapper, StorageMapperFromAddress,
4};
5use crate::{
6 abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
7 api::{ErrorApiImpl, StorageMapperApi},
8 codec::{
9 multi_encode_iter_or_handle_err, EncodeErrorHandler, TopDecode, TopEncode, TopEncodeMulti,
10 TopEncodeMultiOutput,
11 },
12 storage::{storage_clear, storage_set, StorageKey},
13 types::{ManagedAddress, ManagedType, MultiValueEncoded},
14};
15use core::marker::PhantomData;
16
17const ITEM_SUFFIX: &[u8] = b".item";
18const LEN_SUFFIX: &[u8] = b".len";
19
20static INDEX_OUT_OF_RANGE_ERR_MSG: &[u8] = b"index out of range";
21
22pub struct VecMapper<SA, T, A = CurrentStorage>
29where
30 SA: StorageMapperApi,
31 T: TopEncode + TopDecode + 'static,
32{
33 _phantom_api: PhantomData<SA>,
34 address: A,
35 base_key: StorageKey<SA>,
36 len_key: StorageKey<SA>,
37 _phantom_item: PhantomData<T>,
38}
39
40impl<SA, T> StorageMapper<SA> for VecMapper<SA, T, CurrentStorage>
41where
42 SA: StorageMapperApi,
43 T: TopEncode + TopDecode,
44{
45 fn new(base_key: StorageKey<SA>) -> Self {
46 let mut len_key = base_key.clone();
47 len_key.append_bytes(LEN_SUFFIX);
48
49 VecMapper {
50 _phantom_api: PhantomData,
51 address: CurrentStorage,
52 base_key,
53 len_key,
54 _phantom_item: PhantomData,
55 }
56 }
57}
58
59impl<SA, T> StorageMapperFromAddress<SA> for VecMapper<SA, T, ManagedAddress<SA>>
60where
61 SA: StorageMapperApi,
62 T: TopEncode + TopDecode,
63{
64 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
65 let mut len_key = base_key.clone();
66 len_key.append_bytes(LEN_SUFFIX);
67
68 VecMapper {
69 _phantom_api: PhantomData,
70 address,
71 base_key,
72 len_key,
73 _phantom_item: PhantomData,
74 }
75 }
76}
77
78impl<SA, T> StorageClearable for VecMapper<SA, T, CurrentStorage>
79where
80 SA: StorageMapperApi,
81 T: TopEncode + TopDecode,
82{
83 fn clear(&mut self) {
84 self.clear();
85 }
86}
87
88impl<SA, T, A> VecMapper<SA, T, A>
89where
90 SA: StorageMapperApi,
91 A: StorageAddress<SA>,
92 T: TopEncode + TopDecode,
93{
94 fn item_key(&self, index: usize) -> StorageKey<SA> {
95 let mut item_key = self.base_key.clone();
96 item_key.append_bytes(ITEM_SUFFIX);
97 item_key.append_item(&index);
98 item_key
99 }
100
101 pub fn len(&self) -> usize {
103 self.address.address_storage_get(self.len_key.as_ref())
104 }
105
106 pub fn is_empty(&self) -> bool {
108 self.len() == 0
109 }
110
111 pub fn get(&self, index: usize) -> T {
114 if index == 0 || index > self.len() {
115 SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG);
116 }
117 self.get_unchecked(index)
118 }
119
120 pub fn get_unchecked(&self, index: usize) -> T {
124 self.address
125 .address_storage_get(self.item_key(index).as_ref())
126 }
127
128 pub fn get_or_else<F: FnOnce() -> T>(self, index: usize, or_else: F) -> T {
133 if index == 0 || index > self.len() {
134 or_else()
135 } else {
136 self.get_unchecked(index)
137 }
138 }
139
140 pub fn item_is_empty(&self, index: usize) -> bool {
143 if index == 0 || index > self.len() {
144 SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG);
145 }
146 self.item_is_empty_unchecked(index)
147 }
148
149 pub fn item_is_empty_unchecked(&self, index: usize) -> bool {
153 self.address
154 .address_storage_get_len(self.item_key(index).as_ref())
155 == 0
156 }
157
158 #[cfg(feature = "alloc")]
161 pub fn load_as_vec(&self) -> alloc::vec::Vec<T> {
162 self.iter().collect()
163 }
164
165 pub fn iter(&self) -> Iter<'_, SA, T, A> {
167 Iter::new(self)
168 }
169}
170
171impl<SA, T> VecMapper<SA, T, CurrentStorage>
172where
173 SA: StorageMapperApi,
174 T: TopEncode + TopDecode,
175{
176 fn save_count(&self, new_len: usize) {
177 storage_set(self.len_key.as_ref(), &new_len);
178 }
179
180 pub fn push(&mut self, item: &T) -> usize {
183 let mut len = self.len();
184 len += 1;
185 storage_set(self.item_key(len).as_ref(), item);
186 self.save_count(len);
187 len
188 }
189
190 pub fn extend_from_slice(&mut self, items: &[T]) -> usize {
194 let mut len = self.len();
195 for item in items {
196 len += 1;
197 storage_set(self.item_key(len).as_ref(), item);
198 }
199 self.save_count(len);
200 len
201 }
202
203 pub fn set(&mut self, index: usize, item: &T) {
206 if index == 0 || index > self.len() {
207 SA::error_api_impl().signal_error(&b"index out of range"[..]);
208 }
209 self.set_unchecked(index, item);
210 }
211
212 pub fn update<R, F: FnOnce(&mut T) -> R>(&mut self, index: usize, f: F) -> R {
216 let mut value = self.get(index);
217 let result = f(&mut value);
218 self.set(index, &value);
219 result
220 }
221
222 fn set_unchecked(&self, index: usize, item: &T) {
224 storage_set(self.item_key(index).as_ref(), item);
225 }
226
227 pub fn clear_entry(&self, index: usize) {
230 if index == 0 || index > self.len() {
231 SA::error_api_impl().signal_error(&b"index out of range"[..]);
232 }
233 self.clear_entry_unchecked(index)
234 }
235
236 pub fn clear_entry_unchecked(&self, index: usize) {
240 storage_clear(self.item_key(index).as_ref());
241 }
242
243 pub fn swap_remove(&mut self, index: usize) {
247 let _ = self.swap_remove_and_get_old_last(index);
248 }
249
250 pub(crate) fn swap_remove_and_get_old_last(&mut self, index: usize) -> Option<T> {
251 let last_item_index = self.len();
252 if index == 0 || index > last_item_index {
253 SA::error_api_impl().signal_error(&b"index out of range"[..]);
254 }
255
256 let mut last_item_as_option = Option::None;
257 if index != last_item_index {
258 let last_item = self.get(last_item_index);
259 self.set(index, &last_item);
260 last_item_as_option = Some(last_item);
261 }
262 self.clear_entry(last_item_index);
263 self.save_count(last_item_index - 1);
264 last_item_as_option
265 }
266
267 pub fn clear(&mut self) {
270 let len = self.len();
271 for i in 1..=len {
272 storage_clear(self.item_key(i).as_ref());
273 }
274 self.save_count(0);
275 }
276}
277
278impl<'a, SA, T, A> IntoIterator for &'a VecMapper<SA, T, A>
279where
280 SA: StorageMapperApi,
281 A: StorageAddress<SA>,
282 T: TopEncode + TopDecode + 'static,
283{
284 type Item = T;
285
286 type IntoIter = Iter<'a, SA, T, A>;
287
288 fn into_iter(self) -> Self::IntoIter {
289 self.iter()
290 }
291}
292
293pub struct Iter<'a, SA, T, A>
298where
299 SA: StorageMapperApi,
300 A: StorageAddress<SA>,
301 T: TopEncode + TopDecode + 'static,
302{
303 index: usize,
304 len: usize,
305 vec: &'a VecMapper<SA, T, A>,
306}
307
308impl<'a, SA, T, A> Iter<'a, SA, T, A>
309where
310 SA: StorageMapperApi,
311 A: StorageAddress<SA>,
312 T: TopEncode + TopDecode + 'static,
313{
314 fn new(vec: &'a VecMapper<SA, T, A>) -> Iter<'a, SA, T, A> {
315 Iter {
316 index: 1,
317 len: vec.len(),
318 vec,
319 }
320 }
321}
322
323impl<SA, T, A> Iterator for Iter<'_, SA, T, A>
324where
325 SA: StorageMapperApi,
326 A: StorageAddress<SA>,
327 T: TopEncode + TopDecode + 'static,
328{
329 type Item = T;
330
331 #[inline]
332 fn next(&mut self) -> Option<T> {
333 let current_index = self.index;
334 if current_index > self.len {
335 return None;
336 }
337 self.index += 1;
338 Some(self.vec.get_unchecked(current_index))
339 }
340}
341
342impl<SA, T> TopEncodeMulti for VecMapper<SA, T, CurrentStorage>
344where
345 SA: StorageMapperApi,
346 T: TopEncode + TopDecode,
347{
348 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
349 where
350 O: TopEncodeMultiOutput,
351 H: EncodeErrorHandler,
352 {
353 multi_encode_iter_or_handle_err(self.iter(), output, h)
354 }
355}
356
357impl<SA, T> TypeAbiFrom<VecMapper<SA, T, CurrentStorage>> for MultiValueEncoded<SA, T>
358where
359 SA: StorageMapperApi,
360 T: TopEncode + TopDecode,
361{
362}
363
364impl<SA, T> TypeAbiFrom<Self> for VecMapper<SA, T, CurrentStorage>
365where
366 SA: StorageMapperApi,
367 T: TopEncode + TopDecode,
368{
369}
370
371impl<SA, T> TypeAbi for VecMapper<SA, T, CurrentStorage>
373where
374 SA: StorageMapperApi,
375 T: TopEncode + TopDecode + TypeAbi,
376{
377 type Unmanaged = Self;
378
379 fn type_name() -> TypeName {
380 crate::abi::type_name_variadic::<T>()
381 }
382
383 fn type_name_rust() -> TypeName {
384 crate::abi::type_name_multi_value_encoded::<T>()
385 }
386
387 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
388 T::provide_type_descriptions(accumulator);
389 }
390
391 fn is_variadic() -> bool {
392 true
393 }
394}