thruput_sdk/storage/
vector.rs1use super::deletable::Deletable;
2use super::keypath::{FramedComponent, Keypath};
3use super::map::Map;
4use super::node::StorageType;
5use super::slot::{SlotMut, SlotRef};
6use super::value::Value;
7use crate::exn::NoneIfMissing;
8use core::fmt::Debug;
9
10pub struct Vector<S> {
28 keypath: Keypath,
29 len: Value<u32>,
30 values: Map<u32, S>,
31}
32
33impl<S> Debug for Vector<S> {
34 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35 f.debug_struct("Vector")
36 .field("keypath", &self.keypath)
37 .field("len", &self.len)
38 .finish_non_exhaustive()
39 }
40}
41
42impl<S> From<Keypath> for Vector<S> {
43 fn from(keypath: Keypath) -> Self {
44 const LEN_SLOT: FramedComponent = FramedComponent::from_u32(0);
49 const VALUES_SLOT: FramedComponent = FramedComponent::from_u32(1);
50 let len_kp = keypath.child_framed(&LEN_SLOT);
51 let values_kp = keypath.child_framed(&VALUES_SLOT);
52
53 Self {
54 keypath,
55 len: Value::from(len_kp),
56 values: Map::from(values_kp),
57 }
58 }
59}
60
61impl<S> super::sealed::Sealed for Vector<S> {}
62impl<S> super::node::StorageType for Vector<S> {}
63
64impl<S> Vector<S> {
65 pub fn keypath(&self) -> &Keypath {
66 &self.keypath
67 }
68}
69
70impl<S: StorageType> Vector<S> {
71 pub fn len(&self) -> u32 {
82 self.len.try_get().none_if_missing().unwrap_or(0)
83 }
84
85 pub fn is_empty(&self) -> bool {
87 self.len() == 0
88 }
89
90 pub fn at(&self, index: u32) -> SlotRef<'_, Self, S> {
92 self.bounds_check(index);
93 let keypath = self.make_elem_keypath(index);
94 let slot = S::from(keypath);
95 SlotRef::new(self, slot)
96 }
97
98 pub fn at_mut(&mut self, index: u32) -> SlotMut<'_, Self, S> {
110 self.bounds_check(index);
111 let keypath = self.make_elem_keypath(index);
112 let slot = S::from(keypath);
113 SlotMut::new(self, slot)
114 }
115
116 #[must_use = "push_empty_slot increments len immediately; dropping the slot leaves it uninitialized. Use push_with to initialize atomically, or bind with `let _ = ...` if an empty slot is intentional."]
125 pub fn push_empty_slot(&mut self) -> SlotMut<'_, Self, S> {
126 let idx = self.len();
127 let new_len = idx.checked_add(1).unwrap();
128 self.len.set_exclusive(&new_len);
129 let keypath = self.make_elem_keypath(idx);
130 let slot = S::from(keypath);
131 SlotMut::new(self, slot)
132 }
133
134 pub fn push_with<R>(&mut self, f: impl FnOnce(&mut S) -> R) -> R {
143 let idx = self.len();
144 let mut slot = S::from(self.make_elem_keypath(idx));
145 let out = f(&mut slot);
146 let new_len = idx.checked_add(1).unwrap();
147 self.len.set_exclusive(&new_len);
148 out
149 }
150
151 pub fn iter(&self) -> VectorIter<'_, S> {
156 VectorIter {
157 vec: self,
158 index: 0,
159 len: self.len(),
160 }
161 }
162
163 pub fn iter_mut(&mut self) -> VectorIterMut<'_, S> {
167 let len = self.len();
168 VectorIterMut {
169 vec: self,
170 index: 0,
171 len,
172 }
173 }
174
175 fn bounds_check(&self, index: u32) {
176 let len = self.len();
177 if index >= len {
178 super::error::oob_throw(len as u64, index as u64);
179 }
180 }
181
182 fn make_elem_keypath(&self, index: u32) -> Keypath {
183 self.values.keypath().child(&index)
184 }
185}
186
187impl<S: StorageType + Deletable> Vector<S> {
188 pub fn pop(&mut self) {
195 let len = self.len();
196 if len == 0 {
197 super::error::oob_throw(0, 0);
198 }
199 let new_len = len - 1;
200 let mut elem = S::from(self.make_elem_keypath(new_len));
201 elem.delete_exclusive();
202 self.len.set_exclusive(&new_len);
203 }
204
205 #[inline(always)]
212 pub fn delete_at(&mut self, index: u32) {
213 self.at_mut(index).delete();
214 }
215}
216
217impl<S: StorageType + Deletable> Deletable for Vector<S> {
218 fn delete_internal(&mut self, exclusive: bool) {
219 let len = self.len();
220 for i in 0..len {
221 let mut elem = S::from(self.make_elem_keypath(i));
222 elem.delete_internal(exclusive);
223 }
224 self.len.delete_internal(exclusive);
225 }
226}
227
228pub struct VectorIter<'a, S> {
230 vec: &'a Vector<S>,
231 index: u32,
232 len: u32,
233}
234
235impl<'a, S: StorageType> Iterator for VectorIter<'a, S> {
236 type Item = SlotRef<'a, Vector<S>, S>;
237
238 fn next(&mut self) -> Option<Self::Item> {
239 if self.index >= self.len {
240 return None;
241 }
242 let elem = S::from(self.vec.make_elem_keypath(self.index));
243 self.index += 1;
244 Some(SlotRef::new(self.vec, elem))
245 }
246
247 fn size_hint(&self) -> (usize, Option<usize>) {
248 let remaining = (self.len - self.index) as usize;
249 (remaining, Some(remaining))
250 }
251}
252
253impl<S: StorageType> ExactSizeIterator for VectorIter<'_, S> {}
254
255impl<'a, S: StorageType> DoubleEndedIterator for VectorIter<'a, S> {
256 fn next_back(&mut self) -> Option<Self::Item> {
257 if self.index >= self.len {
258 return None;
259 }
260 self.len -= 1;
261 let elem = S::from(self.vec.make_elem_keypath(self.len));
262 Some(SlotRef::new(self.vec, elem))
263 }
264}
265
266pub struct VectorIterMut<'a, S> {
268 vec: &'a mut Vector<S>,
269 index: u32,
270 len: u32,
271}
272
273impl<'a, S: StorageType> Iterator for VectorIterMut<'a, S> {
274 type Item = SlotMut<'a, Vector<S>, S>;
275
276 fn next(&mut self) -> Option<Self::Item> {
277 if self.index >= self.len {
278 return None;
279 }
280 let elem = S::from(self.vec.make_elem_keypath(self.index));
281 self.index += 1;
282 Some(SlotMut::new_detached(elem))
285 }
286
287 fn size_hint(&self) -> (usize, Option<usize>) {
288 let remaining = (self.len - self.index) as usize;
289 (remaining, Some(remaining))
290 }
291}
292
293impl<S: StorageType> ExactSizeIterator for VectorIterMut<'_, S> {}
294
295impl<'a, S: StorageType> DoubleEndedIterator for VectorIterMut<'a, S> {
296 fn next_back(&mut self) -> Option<Self::Item> {
297 if self.index >= self.len {
298 return None;
299 }
300 self.len -= 1;
301 let elem = S::from(self.vec.make_elem_keypath(self.len));
302 Some(SlotMut::new_detached(elem))
303 }
304}
305
306impl<'a, S: StorageType> IntoIterator for &'a Vector<S> {
307 type Item = SlotRef<'a, Vector<S>, S>;
308 type IntoIter = VectorIter<'a, S>;
309
310 fn into_iter(self) -> Self::IntoIter {
311 self.iter()
312 }
313}
314
315impl<'a, S: StorageType> IntoIterator for &'a mut Vector<S> {
316 type Item = SlotMut<'a, Vector<S>, S>;
317 type IntoIter = VectorIterMut<'a, S>;
318
319 fn into_iter(self) -> Self::IntoIter {
320 self.iter_mut()
321 }
322}
323
324#[cfg(test)]
325mod test_vector_slots {
326 use super::*;
327 use crate::storage::Value;
328
329 crate::contract_test!(fixed_slots_match_runtime_child {
332 let root = Keypath::default().child("V");
333 let v: Vector<Value<u32>> = Vector::from(root.clone());
334 assert_eq!(*v.len.key(), root.child(&0u32).generate_key());
335 assert!(v.values.keypath().addresses_same_slot(&root.child(&1u32)));
336 assert!(v.keypath().addresses_same_slot(&root));
337 });
338}