1use core::ops::Range;
4use std::iter::FusedIterator;
5use std::marker::PhantomData;
6
7use borsh::{to_vec, BorshDeserialize, BorshSerialize};
8use unc_sdk_macros::unc;
9
10use crate::collections::append_slice;
11use crate::{env, IntoStorageKey};
12
13const ERR_INCONSISTENT_STATE: &str = "The collection is an inconsistent state. Did previous smart contract execution terminate unexpectedly?";
14const ERR_ELEMENT_DESERIALIZATION: &str = "Cannot deserialize element";
15const ERR_ELEMENT_SERIALIZATION: &str = "Cannot serialize element";
16const ERR_INDEX_OUT_OF_BOUNDS: &str = "Index out of bounds";
17
18fn expect_consistent_state<T>(val: Option<T>) -> T {
19 val.unwrap_or_else(|| env::panic_str(ERR_INCONSISTENT_STATE))
20}
21
22#[unc(inside_uncsdk)]
25pub struct Vector<T> {
26 len: u64,
27 prefix: Vec<u8>,
28 #[borsh(skip)]
29 el: PhantomData<T>,
30}
31
32impl<T> Vector<T> {
33 pub fn len(&self) -> u64 {
35 self.len
36 }
37
38 pub fn is_empty(&self) -> bool {
40 self.len == 0
41 }
42
43 pub fn new<S>(prefix: S) -> Self
52 where
53 S: IntoStorageKey,
54 {
55 Self { len: 0, prefix: prefix.into_storage_key(), el: PhantomData }
56 }
57
58 #[cfg(feature = "unstable")]
65 pub fn to_v2(&self) -> crate::store::Vector<T>
66 where
67 T: BorshSerialize,
68 {
69 crate::store::Vector {
70 len: self.len.try_into().unwrap(),
72 values: crate::store::IndexMap::new(self.prefix.as_slice()),
73 }
74 }
75
76 fn index_to_lookup_key(&self, index: u64) -> Vec<u8> {
77 append_slice(&self.prefix, &index.to_le_bytes()[..])
78 }
79
80 pub fn get_raw(&self, index: u64) -> Option<Vec<u8>> {
82 if index >= self.len {
83 return None;
84 }
85 let lookup_key = self.index_to_lookup_key(index);
86 Some(expect_consistent_state(env::storage_read(&lookup_key)))
87 }
88
89 pub fn swap_remove_raw(&mut self, index: u64) -> Vec<u8> {
97 if index >= self.len {
98 env::panic_str(ERR_INDEX_OUT_OF_BOUNDS)
99 } else if index + 1 == self.len {
100 expect_consistent_state(self.pop_raw())
101 } else {
102 let lookup_key = self.index_to_lookup_key(index);
103 let raw_last_value = self.pop_raw().expect("checked `index < len` above, so `len > 0`");
104 if env::storage_write(&lookup_key, &raw_last_value) {
105 expect_consistent_state(env::storage_get_evicted())
106 } else {
107 env::panic_str(ERR_INCONSISTENT_STATE)
108 }
109 }
110 }
111
112 pub fn push_raw(&mut self, raw_element: &[u8]) {
114 let lookup_key = self.index_to_lookup_key(self.len);
115 self.len += 1;
116 env::storage_write(&lookup_key, raw_element);
117 }
118
119 pub fn pop_raw(&mut self) -> Option<Vec<u8>> {
121 if self.is_empty() {
122 None
123 } else {
124 let last_index = self.len - 1;
125 let last_lookup_key = self.index_to_lookup_key(last_index);
126
127 self.len -= 1;
128 let raw_last_value = if env::storage_remove(&last_lookup_key) {
129 expect_consistent_state(env::storage_get_evicted())
130 } else {
131 env::panic_str(ERR_INCONSISTENT_STATE)
132 };
133 Some(raw_last_value)
134 }
135 }
136
137 pub fn replace_raw(&mut self, index: u64, raw_element: &[u8]) -> Vec<u8> {
143 if index >= self.len {
144 env::panic_str(ERR_INDEX_OUT_OF_BOUNDS)
145 } else {
146 let lookup_key = self.index_to_lookup_key(index);
147 if env::storage_write(&lookup_key, raw_element) {
148 expect_consistent_state(env::storage_get_evicted())
149 } else {
150 env::panic_str(ERR_INCONSISTENT_STATE);
151 }
152 }
153 }
154
155 pub fn iter_raw(&self) -> RawIter<T> {
157 RawIter::new(self)
158 }
159
160 pub fn extend_raw<IT: IntoIterator<Item = Vec<u8>>>(&mut self, iter: IT) {
162 for el in iter {
163 self.push_raw(&el)
164 }
165 }
166}
167
168impl<T> Vector<T> {
169 pub fn clear(&mut self) {
171 for i in 0..self.len {
172 let lookup_key = self.index_to_lookup_key(i);
173 env::storage_remove(&lookup_key);
174 }
175 self.len = 0;
176 }
177}
178
179impl<T> Vector<T>
180where
181 T: BorshSerialize,
182{
183 fn serialize_element(element: &T) -> Vec<u8> {
184 to_vec(element).unwrap_or_else(|_| env::panic_str(ERR_ELEMENT_SERIALIZATION))
185 }
186
187 pub fn push(&mut self, element: &T) {
189 let raw_element = Self::serialize_element(element);
190 self.push_raw(&raw_element);
191 }
192
193 pub fn extend<IT: IntoIterator<Item = T>>(&mut self, iter: IT) {
195 for el in iter {
196 self.push(&el)
197 }
198 }
199}
200
201impl<T> Vector<T>
202where
203 T: BorshDeserialize,
204{
205 fn deserialize_element(raw_element: &[u8]) -> T {
206 T::try_from_slice(raw_element)
207 .unwrap_or_else(|_| env::panic_str(ERR_ELEMENT_DESERIALIZATION))
208 }
209
210 pub fn get(&self, index: u64) -> Option<T> {
212 self.get_raw(index).map(|x| Self::deserialize_element(&x))
213 }
214
215 pub fn swap_remove(&mut self, index: u64) -> T {
223 let raw_evicted = self.swap_remove_raw(index);
224 Self::deserialize_element(&raw_evicted)
225 }
226
227 pub fn pop(&mut self) -> Option<T> {
229 self.pop_raw().map(|x| Self::deserialize_element(&x))
230 }
231
232 pub fn iter(&self) -> Iter<T> {
234 Iter::new(self)
235 }
236
237 pub fn to_vec(&self) -> Vec<T> {
238 self.iter().collect()
239 }
240}
241
242impl<T> Vector<T>
243where
244 T: BorshSerialize + BorshDeserialize,
245{
246 pub fn replace(&mut self, index: u64, element: &T) -> T {
252 let raw_element = Self::serialize_element(element);
253 Self::deserialize_element(&self.replace_raw(index, &raw_element))
254 }
255}
256
257#[cfg(feature = "expensive-debug")]
258impl<T: std::fmt::Debug + BorshDeserialize> std::fmt::Debug for Vector<T> {
259 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
260 self.to_vec().fmt(f)
261 }
262}
263
264#[cfg(not(feature = "expensive-debug"))]
265impl<T: std::fmt::Debug + BorshDeserialize> std::fmt::Debug for Vector<T> {
266 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
267 f.debug_struct("Vector").field("len", &self.len).field("prefix", &self.prefix).finish()
268 }
269}
270
271pub struct RawIter<'a, T> {
273 vec: &'a Vector<T>,
274 range: Range<u64>,
275}
276
277impl<'a, T> RawIter<'a, T> {
278 fn new(vec: &'a Vector<T>) -> Self {
279 Self { vec, range: Range { start: 0, end: vec.len() } }
280 }
281
282 fn remaining(&self) -> usize {
284 (self.range.end - self.range.start) as usize
285 }
286}
287
288impl<'a, T> Iterator for RawIter<'a, T> {
289 type Item = Vec<u8>;
290
291 fn next(&mut self) -> Option<Self::Item> {
292 <Self as Iterator>::nth(self, 0)
293 }
294
295 fn size_hint(&self) -> (usize, Option<usize>) {
296 let remaining = self.remaining();
297 (remaining, Some(remaining))
298 }
299
300 fn count(self) -> usize {
301 self.remaining()
302 }
303
304 fn nth(&mut self, n: usize) -> Option<Self::Item> {
305 let idx = self.range.nth(n)?;
306 self.vec.get_raw(idx)
307 }
308}
309
310impl<'a, T> ExactSizeIterator for RawIter<'a, T> {}
311impl<'a, T> FusedIterator for RawIter<'a, T> {}
312
313impl<'a, T> DoubleEndedIterator for RawIter<'a, T> {
314 fn next_back(&mut self) -> Option<Self::Item> {
315 <Self as DoubleEndedIterator>::nth_back(self, 0)
316 }
317
318 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
319 let idx = self.range.nth_back(n)?;
320 self.vec.get_raw(idx)
321 }
322}
323
324pub struct Iter<'a, T> {
326 inner: RawIter<'a, T>,
327}
328
329impl<'a, T> Iter<'a, T> {
330 fn new(vec: &'a Vector<T>) -> Self {
331 Self { inner: RawIter::new(vec) }
332 }
333}
334
335impl<'a, T> Iterator for Iter<'a, T>
336where
337 T: BorshDeserialize,
338{
339 type Item = T;
340
341 fn next(&mut self) -> Option<Self::Item> {
342 <Self as Iterator>::nth(self, 0)
343 }
344
345 fn size_hint(&self) -> (usize, Option<usize>) {
346 let remaining = self.inner.remaining();
347 (remaining, Some(remaining))
348 }
349
350 fn count(self) -> usize {
351 self.inner.remaining()
352 }
353
354 fn nth(&mut self, n: usize) -> Option<Self::Item> {
355 self.inner.nth(n).map(|raw_element| Vector::deserialize_element(&raw_element))
356 }
357}
358
359impl<'a, T> ExactSizeIterator for Iter<'a, T> where T: BorshDeserialize {}
360impl<'a, T> FusedIterator for Iter<'a, T> where T: BorshDeserialize {}
361
362impl<'a, T> DoubleEndedIterator for Iter<'a, T>
363where
364 T: BorshDeserialize,
365{
366 fn next_back(&mut self) -> Option<Self::Item> {
367 <Self as DoubleEndedIterator>::nth_back(self, 0)
368 }
369
370 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
371 self.inner.nth_back(n).map(|raw_element| Vector::deserialize_element(&raw_element))
372 }
373}
374
375#[cfg(not(target_arch = "wasm32"))]
376#[cfg(test)]
377mod tests {
378 use borsh::BorshDeserialize;
379 use rand::{Rng, SeedableRng};
380
381 use crate::collections::Vector;
382
383 #[test]
384 fn test_push_pop() {
385 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(0);
386 let mut vec = Vector::new(b"v".to_vec());
387 let mut baseline = vec![];
388 for _ in 0..500 {
389 let value = rng.gen::<u64>();
390 vec.push(&value);
391 baseline.push(value);
392 }
393 let actual = vec.to_vec();
394 assert_eq!(actual, baseline);
395 for _ in 0..1001 {
396 assert_eq!(baseline.pop(), vec.pop());
397 }
398 }
399
400 #[test]
401 pub fn test_replace() {
402 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(1);
403 let mut vec = Vector::new(b"v".to_vec());
404 let mut baseline = vec![];
405 for _ in 0..500 {
406 let value = rng.gen::<u64>();
407 vec.push(&value);
408 baseline.push(value);
409 }
410 for _ in 0..500 {
411 let index = rng.gen::<u64>() % vec.len();
412 let value = rng.gen::<u64>();
413 let old_value0 = vec.get(index).unwrap();
414 let old_value1 = vec.replace(index, &value);
415 let old_value2 = baseline[index as usize];
416 assert_eq!(old_value0, old_value1);
417 assert_eq!(old_value0, old_value2);
418 *baseline.get_mut(index as usize).unwrap() = value;
419 }
420 let actual = vec.to_vec();
421 assert_eq!(actual, baseline);
422 }
423
424 #[test]
425 pub fn test_swap_remove() {
426 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(2);
427 let mut vec = Vector::new(b"v".to_vec());
428 let mut baseline = vec![];
429 for _ in 0..500 {
430 let value = rng.gen::<u64>();
431 vec.push(&value);
432 baseline.push(value);
433 }
434 for _ in 0..500 {
435 let index = rng.gen::<u64>() % vec.len();
436 let old_value0 = vec.get(index).unwrap();
437 let old_value1 = vec.swap_remove(index);
438 let old_value2 = baseline[index as usize];
439 let last_index = baseline.len() - 1;
440 baseline.swap(index as usize, last_index);
441 baseline.pop();
442 assert_eq!(old_value0, old_value1);
443 assert_eq!(old_value0, old_value2);
444 }
445 let actual = vec.to_vec();
446 assert_eq!(actual, baseline);
447 }
448
449 #[test]
450 pub fn test_clear() {
451 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(3);
452 let mut vec = Vector::new(b"v".to_vec());
453 for _ in 0..100 {
454 for _ in 0..(rng.gen::<u64>() % 20 + 1) {
455 let value = rng.gen::<u64>();
456 vec.push(&value);
457 }
458 assert!(!vec.is_empty());
459 vec.clear();
460 assert!(vec.is_empty());
461 }
462 }
463
464 #[test]
465 pub fn test_extend() {
466 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(0);
467 let mut vec = Vector::new(b"v".to_vec());
468 let mut baseline = vec![];
469 for _ in 0..100 {
470 let value = rng.gen::<u64>();
471 vec.push(&value);
472 baseline.push(value);
473 }
474
475 for _ in 0..100 {
476 let mut tmp = vec![];
477 for _ in 0..=(rng.gen::<u64>() % 20 + 1) {
478 let value = rng.gen::<u64>();
479 tmp.push(value);
480 }
481 baseline.extend(tmp.clone());
482 vec.extend(tmp.clone());
483 }
484 let actual = vec.to_vec();
485 assert_eq!(actual, baseline);
486 }
487
488 #[test]
489 fn test_debug() {
490 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
491 let prefix = b"v".to_vec();
492 let mut vec = Vector::new(prefix.clone());
493 let mut baseline = vec![];
494 for _ in 0..10 {
495 let value = rng.gen::<u64>();
496 vec.push(&value);
497 baseline.push(value);
498 }
499 let actual = vec.to_vec();
500 assert_eq!(actual, baseline);
501 for _ in 0..5 {
502 assert_eq!(baseline.pop(), vec.pop());
503 }
504 if cfg!(feature = "expensive-debug") {
505 assert_eq!(format!("{:#?}", vec), format!("{:#?}", baseline));
506 } else {
507 assert_eq!(
508 format!("{:?}", vec),
509 format!("Vector {{ len: 5, prefix: {:?} }}", vec.prefix)
510 );
511 }
512
513 #[derive(Debug, BorshDeserialize)]
514 #[allow(dead_code)]
515 struct WithoutBorshSerialize(u64);
516
517 let deserialize_only_vec =
518 Vector::<WithoutBorshSerialize> { len: vec.len(), prefix, el: Default::default() };
519 let baseline: Vec<_> = baseline.into_iter().map(WithoutBorshSerialize).collect();
520 if cfg!(feature = "expensive-debug") {
521 assert_eq!(format!("{:#?}", deserialize_only_vec), format!("{:#?}", baseline));
522 } else {
523 assert_eq!(
524 format!("{:?}", deserialize_only_vec),
525 format!("Vector {{ len: 5, prefix: {:?} }}", deserialize_only_vec.prefix)
526 );
527 }
528 }
529
530 #[test]
531 pub fn iterator_checks() {
532 let mut vec = Vector::new(b"v");
533 let mut baseline = vec![];
534 for i in 0..10 {
535 vec.push(&i);
536 baseline.push(i);
537 }
538
539 let mut vec_iter = vec.iter();
540 let mut bl_iter = baseline.iter();
541 assert_eq!(vec_iter.next(), bl_iter.next().copied());
542 assert_eq!(vec_iter.next_back(), bl_iter.next_back().copied());
543 assert_eq!(vec_iter.nth(3), bl_iter.nth(3).copied());
544 assert_eq!(vec_iter.nth_back(2), bl_iter.nth_back(2).copied());
545
546 assert!(vec_iter.nth(5).is_none());
548 assert!(bl_iter.nth(5).is_none());
549
550 assert!(vec_iter.next().is_none());
551 assert!(bl_iter.next().is_none());
552
553 assert_eq!(vec.iter().count(), baseline.len());
555 }
556}