unc_sdk/store/vec/mod.rs
1//! A growable array type with values persisted to storage and lazily loaded.
2//!
3//! Values in the [`Vector`] are kept in an in-memory cache and are only persisted on [`Drop`].
4//!
5//! Vectors ensure they never allocate more than [`u32::MAX`] bytes. [`u32`] is used rather than
6//! [`usize`] as in [`Vec`] to ensure consistent behavior on different targets.
7//!
8//! # Examples
9//!
10//! You can explicitly create a [`Vector`] with [`Vector::new`]:
11//!
12//! ```
13//! use unc_sdk::store::Vector;
14//!
15//! let v: Vector<i32> = Vector::new(b"a");
16//! ```
17//!
18//! You can [`push`](Vector::push) values onto the end of a vector (which will grow the vector
19//! as needed):
20//!
21//! ```
22//! use unc_sdk::store::Vector;
23//!
24//! let mut v: Vector<i32> = Vector::new(b"a");
25//!
26//! v.push(3);
27//! ```
28//!
29//! Popping values works in much the same way:
30//!
31//! ```
32//! use unc_sdk::store::Vector;
33//!
34//! let mut v: Vector<i32> = Vector::new(b"a");
35//! v.extend([1, 2]);
36//!
37//! let two = v.pop();
38//! ```
39//!
40//! Vectors also support indexing (through the [`Index`] and [`IndexMut`] traits):
41//!
42//! ```
43//! use unc_sdk::store::Vector;
44//!
45//! let mut v: Vector<i32> = Vector::new(b"a");
46//! v.extend([1, 2, 3]);
47//!
48//! let three = v[2];
49//! v[1] = v[1] + 5;
50//! ```
51//!
52//! [`Index`]: std::ops::Index
53//! [`IndexMut`]: std::ops::IndexMut
54
55mod impls;
56mod iter;
57
58use std::{
59 fmt,
60 ops::{Bound, Range, RangeBounds},
61};
62
63use borsh::{BorshDeserialize, BorshSerialize};
64use unc_sdk_macros::UncSchema;
65
66pub use self::iter::{Drain, Iter, IterMut};
67use super::ERR_INCONSISTENT_STATE;
68use crate::{env, IntoStorageKey};
69
70use super::IndexMap;
71
72const ERR_INDEX_OUT_OF_BOUNDS: &str = "Index out of bounds";
73
74fn expect_consistent_state<T>(val: Option<T>) -> T {
75 val.unwrap_or_else(|| env::panic_str(ERR_INCONSISTENT_STATE))
76}
77
78/// An iterable implementation of vector that stores its content on the trie. This implementation
79/// will load and store values in the underlying storage lazily.
80///
81/// Uses the following map: index -> element. Because the data is sharded to avoid reading/writing
82/// large chunks of data, the values cannot be accessed as a contiguous piece of memory.
83///
84/// This implementation will cache all changes and loads and only updates values that are changed
85/// in storage after it's dropped through it's [`Drop`] implementation. These changes can be updated
86/// in storage before the variable is dropped by using [`Vector::flush`]. During the lifetime of
87/// this type, storage will only be read a maximum of one time per index and only written once per
88/// index unless specifically flushed.
89///
90/// This type should be a drop in replacement for [`Vec`] in most cases and will provide contracts
91/// a vector structure which scales much better as the contract data grows.
92///
93/// # Examples
94/// ```
95/// use unc_sdk::store::Vector;
96///
97/// let mut vec = Vector::new(b"a");
98/// assert!(vec.is_empty());
99///
100/// vec.push(1);
101/// vec.push(2);
102///
103/// assert_eq!(vec.len(), 2);
104/// assert_eq!(vec[0], 1);
105///
106/// assert_eq!(vec.pop(), Some(2));
107/// assert_eq!(vec.len(), 1);
108///
109/// vec[0] = 7;
110/// assert_eq!(vec[0], 7);
111///
112/// vec.extend([1, 2, 3].iter().copied());
113/// assert!(Iterator::eq(vec.into_iter(), [7, 1, 2, 3].iter()));
114/// ```
115#[derive(UncSchema, BorshSerialize, BorshDeserialize)]
116#[inside_uncsdk]
117#[abi(borsh)]
118pub struct Vector<T>
119where
120 T: BorshSerialize,
121{
122 pub(crate) len: u32,
123 // ser/de is independent of `T` ser/de, `BorshSerialize`/`BorshDeserialize`/`BorshSchema` bounds removed
124 #[cfg_attr(not(feature = "abi"), borsh(bound(serialize = "", deserialize = "")))]
125 #[cfg_attr(
126 feature = "abi",
127 borsh(bound(serialize = "", deserialize = ""), schema(params = ""))
128 )]
129 pub(crate) values: IndexMap<T>,
130}
131
132#[test]
133fn collections_vec_not_backwards_compatible() {
134 use crate::collections::Vector as Vec1;
135
136 let mut v1 = Vec1::new(b"m");
137 v1.extend([1u8, 2, 3, 4]);
138 // Old collections serializes length as `u64` when new serializes as `u32`.
139 assert!(Vector::<u8>::try_from_slice(&borsh::to_vec(&v1).unwrap()).is_err());
140}
141
142impl<T> Vector<T>
143where
144 T: BorshSerialize,
145{
146 /// Returns the number of elements in the vector, also referred to as its size.
147 /// This function returns a `u32` rather than the [`Vec`] equivalent of `usize` to have
148 /// consistency between targets.
149 ///
150 /// # Examples
151 ///
152 /// ```
153 /// use unc_sdk::store::Vector;
154 ///
155 /// let mut vec = Vector::new(b"a");
156 /// vec.push(1);
157 /// vec.push(2);
158 /// assert_eq!(vec.len(), 2);
159 /// ```
160 pub fn len(&self) -> u32 {
161 self.len
162 }
163
164 /// Returns `true` if the vector contains no elements.
165 ///
166 /// # Examples
167 ///
168 /// ```
169 /// use unc_sdk::store::Vector;
170 ///
171 /// let mut vec = Vector::new(b"a");
172 /// assert!(vec.is_empty());
173 ///
174 /// vec.push(1);
175 /// assert!(!vec.is_empty());
176 /// ```
177 pub fn is_empty(&self) -> bool {
178 self.len == 0
179 }
180
181 /// Create new vector with zero elements. Prefixes storage access with the prefix provided.
182 ///
183 /// This prefix can be anything that implements [`IntoStorageKey`]. The prefix is used when
184 /// storing and looking up values in storage to ensure no collisions with other collections.
185 ///
186 /// # Examples
187 ///
188 /// ```
189 /// use unc_sdk::store::Vector;
190 ///
191 /// let mut vec: Vector<u8> = Vector::new(b"a");
192 /// ```
193 pub fn new<S>(prefix: S) -> Self
194 where
195 S: IntoStorageKey,
196 {
197 Self { len: 0, values: IndexMap::new(prefix) }
198 }
199
200 /// Removes all elements from the collection. This will remove all storage values for the
201 /// length of the [`Vector`].
202 ///
203 /// # Examples
204 ///
205 /// ```
206 /// use unc_sdk::store::Vector;
207 ///
208 /// let mut vec = Vector::new(b"a");
209 /// vec.push(1);
210 ///
211 /// vec.clear();
212 ///
213 /// assert!(vec.is_empty());
214 /// ```
215 pub fn clear(&mut self) {
216 for i in 0..self.len {
217 self.values.set(i, None);
218 }
219 self.len = 0;
220 }
221
222 /// Flushes the cache and writes all modified values to storage.
223 ///
224 /// This operation is performed on [`Drop`], but this method can be called to persist
225 /// intermediate writes in cases where [`Drop`] is not called or to identify storage changes.
226 pub fn flush(&mut self) {
227 self.values.flush();
228 }
229
230 /// Sets a value at a given index to the value provided. This does not shift values after the
231 /// index to the right.
232 ///
233 /// The reason to use this over modifying with [`Vector::get_mut`] or
234 /// [`IndexMut::index_mut`](core::ops::IndexMut::index_mut) is to avoid loading the existing
235 /// value from storage. This method will just write the new value.
236 ///
237 /// # Panics
238 ///
239 /// Panics if `index` is out of bounds.
240 ///
241 /// # Examples
242 ///
243 /// ```
244 /// use unc_sdk::store::Vector;
245 ///
246 /// let mut vec = Vector::new(b"v");
247 /// vec.push("test".to_string());
248 ///
249 /// vec.set(0,"new_value".to_string());
250 ///
251 /// assert_eq!(vec.get(0),Some(&"new_value".to_string()));
252 /// ```
253 pub fn set(&mut self, index: u32, value: T) {
254 if index >= self.len() {
255 env::panic_str(ERR_INDEX_OUT_OF_BOUNDS);
256 }
257
258 self.values.set(index, Some(value));
259 }
260
261 /// Appends an element to the back of the collection.
262 ///
263 /// # Panics
264 ///
265 /// Panics if new length exceeds `u32::MAX`
266 ///
267 /// # Examples
268 ///
269 /// ```
270 /// use unc_sdk::store::Vector;
271 ///
272 /// let mut vec = Vector::new(b"v");
273 /// vec.push("test".to_string());
274 ///
275 /// assert!(!vec.is_empty());
276 /// ```
277 pub fn push(&mut self, element: T) {
278 let last_idx = self.len();
279 self.len =
280 self.len.checked_add(1).unwrap_or_else(|| env::panic_str(ERR_INDEX_OUT_OF_BOUNDS));
281 self.set(last_idx, element)
282 }
283}
284
285impl<T> Vector<T>
286where
287 T: BorshSerialize + BorshDeserialize,
288{
289 /// Returns the element by index or `None` if it is not present.
290 ///
291 /// # Examples
292 ///
293 /// ```
294 /// use unc_sdk::store::Vector;
295 ///
296 /// let mut vec = Vector::new(b"v");
297 /// vec.push("test".to_string());
298 ///
299 /// assert_eq!(Some(&"test".to_string()), vec.get(0));
300 /// assert_eq!(None, vec.get(3));
301 /// ```
302 pub fn get(&self, index: u32) -> Option<&T> {
303 if index >= self.len() {
304 return None;
305 }
306 self.values.get(index)
307 }
308
309 /// Returns a mutable reference to the element at the `index` provided.
310 ///
311 /// # Examples
312 ///
313 /// ```
314 /// use unc_sdk::store::Vector;
315 ///
316 /// let mut vec = Vector::new(b"v");
317 /// let x = vec![0, 1, 2];
318 /// vec.extend(x);
319 ///
320 /// if let Some(elem) = vec.get_mut(1) {
321 /// *elem = 42;
322 /// }
323 ///
324 /// let actual: Vec<_> = vec.iter().cloned().collect();
325 /// assert_eq!(actual, &[0, 42, 2]);
326 /// ```
327 pub fn get_mut(&mut self, index: u32) -> Option<&mut T> {
328 if index >= self.len {
329 return None;
330 }
331 self.values.get_mut(index)
332 }
333
334 pub(crate) fn swap(&mut self, a: u32, b: u32) {
335 if a >= self.len() || b >= self.len() {
336 env::panic_str(ERR_INDEX_OUT_OF_BOUNDS);
337 }
338
339 self.values.swap(a, b);
340 }
341
342 /// Removes an element from the vector and returns it.
343 /// The removed element is replaced by the last element of the vector.
344 /// Does not preserve ordering, but is `O(1)`.
345 ///
346 /// # Panics
347 ///
348 /// Panics if `index` is out of bounds.
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// use unc_sdk::store::Vector;
354 ///
355 /// let mut vec: Vector<u8> = Vector::new(b"v");
356 /// vec.extend([1, 2, 3, 4]);
357 ///
358 /// assert_eq!(vec.swap_remove(1), 2);
359 /// assert_eq!(vec.iter().copied().collect::<Vec<_>>(), &[1, 4, 3]);
360 ///
361 /// assert_eq!(vec.swap_remove(0), 1);
362 /// assert_eq!(vec.iter().copied().collect::<Vec<_>>(), &[3, 4]);
363 /// ```
364 pub fn swap_remove(&mut self, index: u32) -> T {
365 if self.is_empty() {
366 env::panic_str(ERR_INDEX_OUT_OF_BOUNDS);
367 }
368
369 self.swap(index, self.len() - 1);
370 expect_consistent_state(self.pop())
371 }
372
373 /// Removes the last element from a vector and returns it, or [`None`] if it is empty.
374 ///
375 /// # Examples
376 ///
377 /// ```
378 /// use unc_sdk::store::Vector;
379 ///
380 /// let mut vec = Vector::new(b"v");
381 /// vec.extend([1, 2, 3]);
382 ///
383 /// assert_eq!(vec.pop(), Some(3));
384 /// assert_eq!(vec.pop(), Some(2));
385 /// ```
386 pub fn pop(&mut self) -> Option<T> {
387 let new_idx = self.len.checked_sub(1)?;
388 let prev = self.values.remove(new_idx);
389 self.len = new_idx;
390 prev
391 }
392
393 /// Inserts a element at `index`, returns an evicted element.
394 ///
395 /// # Panics
396 ///
397 /// If `index` is out of bounds.
398 ///
399 /// # Examples
400 ///
401 /// ```
402 /// use unc_sdk::store::Vector;
403 ///
404 /// let mut vec = Vector::new(b"v");
405 /// vec.push("test".to_string());
406 ///
407 /// vec.replace(0,"replaced".to_string());
408 ///
409 /// assert_eq!(vec.get(0), Some(&"replaced".to_string()));
410 /// ```
411 pub fn replace(&mut self, index: u32, element: T) -> T {
412 if index >= self.len {
413 env::panic_str(ERR_INDEX_OUT_OF_BOUNDS);
414 }
415 self.values.insert(index, element).unwrap()
416 }
417
418 /// Returns an iterator over the vector. This iterator will lazily load any values iterated
419 /// over from storage.
420 ///
421 /// # Examples
422 ///
423 /// ```
424 /// use unc_sdk::store::Vector;
425 ///
426 /// let mut vec = Vector::new(b"v");
427 /// vec.extend([1, 2, 4]);
428 /// let mut iterator = vec.iter();
429 ///
430 /// assert_eq!(iterator.next(), Some(&1));
431 /// assert_eq!(iterator.next(), Some(&2));
432 /// assert_eq!(iterator.next(), Some(&4));
433 /// assert_eq!(iterator.next(), None);
434 /// ```
435 pub fn iter(&self) -> Iter<T> {
436 Iter::new(self)
437 }
438
439 /// Returns an iterator over the [`Vector`] that allows modifying each value. This iterator
440 /// will lazily load any values iterated over from storage.
441 ///
442 /// # Examples
443 ///
444 /// ```
445 /// use unc_sdk::store::Vector;
446 ///
447 /// let mut vec = Vector::new(b"v");
448 /// vec.extend([1u32, 2, 4]);
449 ///
450 /// for elem in vec.iter_mut() {
451 /// *elem += 2;
452 /// }
453 /// assert_eq!(vec.iter().copied().collect::<Vec<_>>(), &[3u32, 4, 6]);
454 /// ```
455 pub fn iter_mut(&mut self) -> IterMut<T> {
456 IterMut::new(self)
457 }
458
459 /// Creates a draining iterator that removes the specified range in the vector
460 /// and yields the removed items.
461 ///
462 /// When the iterator **is** dropped, all elements in the range are removed
463 /// from the vector, even if the iterator was not fully consumed. If the
464 /// iterator **is not** dropped (with [`mem::forget`](std::mem::forget) for example),
465 /// the collection will be left in an inconsistent state.
466 ///
467 /// This will not panic on invalid ranges (`end > length` or `end < start`) and instead the
468 /// iterator will just be empty.
469 ///
470 /// # Examples
471 ///
472 /// ```
473 /// use unc_sdk::store::Vector;
474 ///
475 /// let mut vec: Vector<u32> = Vector::new(b"v");
476 /// vec.extend(vec![1, 2, 3]);
477 ///
478 /// let u: Vec<_> = vec.drain(1..).collect();
479 /// assert_eq!(vec.iter().copied().collect::<Vec<_>>(), &[1]);
480 /// assert_eq!(u, &[2, 3]);
481 ///
482 /// // A full range clears the vector, like `clear()` does
483 /// vec.drain(..);
484 /// assert!(vec.is_empty());
485 /// ```
486 pub fn drain<R>(&mut self, range: R) -> Drain<T>
487 where
488 R: RangeBounds<u32>,
489 {
490 let start = match range.start_bound() {
491 Bound::Excluded(i) => {
492 i.checked_add(1).unwrap_or_else(|| env::panic_str(ERR_INDEX_OUT_OF_BOUNDS))
493 }
494 Bound::Included(i) => *i,
495 Bound::Unbounded => 0,
496 };
497 let end = match range.end_bound() {
498 Bound::Excluded(i) => *i,
499 Bound::Included(i) => {
500 i.checked_add(1).unwrap_or_else(|| env::panic_str(ERR_INDEX_OUT_OF_BOUNDS))
501 }
502 Bound::Unbounded => self.len(),
503 };
504
505 // Note: don't need to do bounds check if end < start, will just return None when iterating
506 // This will also cap the max length at the length of the vector.
507 Drain::new(self, Range { start, end: core::cmp::min(end, self.len()) })
508 }
509}
510
511impl<T> fmt::Debug for Vector<T>
512where
513 T: BorshSerialize + BorshDeserialize + fmt::Debug,
514{
515 #[cfg(feature = "expensive-debug")]
516 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
517 fmt::Debug::fmt(&self.iter().collect::<Vec<_>>(), f)
518 }
519
520 #[cfg(not(feature = "expensive-debug"))]
521 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
522 f.debug_struct("Vector")
523 .field("len", &self.len)
524 .field("prefix", &self.values.prefix)
525 .finish()
526 }
527}
528
529#[cfg(not(target_arch = "wasm32"))]
530#[cfg(test)]
531mod tests {
532 use arbitrary::{Arbitrary, Unstructured};
533 use borsh::{to_vec, BorshDeserialize};
534 use rand::{Rng, RngCore, SeedableRng};
535 use std::ops::{Bound, IndexMut};
536
537 use super::Vector;
538 use crate::{store::IndexMap, test_utils::test_env::setup_free};
539
540 #[test]
541 fn test_push_pop() {
542 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(0);
543 let mut vec = Vector::new(b"v".to_vec());
544 let mut baseline = vec![];
545 for _ in 0..500 {
546 let value = rng.gen::<u64>();
547 vec.push(value);
548 baseline.push(value);
549 }
550 let actual: Vec<u64> = vec.iter().cloned().collect();
551 assert_eq!(actual, baseline);
552 for _ in 0..501 {
553 assert_eq!(baseline.pop(), vec.pop());
554 }
555 }
556
557 #[test]
558 #[should_panic]
559 fn test_set_panic() {
560 let mut vec = Vector::new(b"b");
561 vec.set(2, 0);
562 }
563
564 #[test]
565 fn test_get_mut_none() {
566 let mut vec: Vector<bool> = Vector::new(b"b");
567 assert!(vec.get_mut(2).is_none());
568 }
569
570 #[test]
571 #[should_panic]
572 fn test_drain_panic() {
573 let mut vec: Vector<bool> = Vector::new(b"b");
574 vec.drain(..=u32::MAX);
575 }
576
577 #[test]
578 #[should_panic]
579 fn test_drain_panic_2() {
580 let mut vec: Vector<bool> = Vector::new(b"b");
581 vec.drain((Bound::Excluded(u32::MAX), Bound::Included(u32::MAX)));
582 }
583
584 #[test]
585 fn test_replace_method() {
586 let mut vec = Vector::new(b"b");
587 vec.push(10);
588 vec.replace(0, 2);
589 assert_eq!(vec[0], 2);
590 }
591
592 #[test]
593 #[should_panic]
594 fn test_replace_method_panic() {
595 let mut vec = Vector::new(b"b");
596 vec.replace(0, 2);
597 }
598
599 #[test]
600 pub fn test_replace() {
601 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(1);
602 let mut vec = Vector::new(b"v".to_vec());
603 let mut baseline = vec![];
604 for _ in 0..500 {
605 let value = rng.gen::<u64>();
606 vec.push(value);
607 baseline.push(value);
608 }
609 for _ in 0..500 {
610 let index = rng.gen::<u32>() % vec.len();
611 let value = rng.gen::<u64>();
612 let old_value0 = vec[index];
613 let old_value1 = core::mem::replace(vec.get_mut(index).unwrap(), value);
614 let old_value2 = baseline[index as usize];
615 assert_eq!(old_value0, old_value1);
616 assert_eq!(old_value0, old_value2);
617 *baseline.get_mut(index as usize).unwrap() = value;
618 }
619 let actual: Vec<_> = vec.iter().cloned().collect();
620 assert_eq!(actual, baseline);
621 }
622
623 #[test]
624 pub fn test_swap_remove() {
625 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(2);
626 let mut vec = Vector::new(b"v".to_vec());
627 let mut baseline = vec![];
628 for _ in 0..500 {
629 let value = rng.gen::<u64>();
630 vec.push(value);
631 baseline.push(value);
632 }
633 for _ in 0..500 {
634 let index = rng.gen::<u32>() % vec.len();
635 let old_value0 = vec[index];
636 let old_value1 = vec.swap_remove(index);
637 let old_value2 = baseline[index as usize];
638 let last_index = baseline.len() - 1;
639 baseline.swap(index as usize, last_index);
640 baseline.pop();
641 assert_eq!(old_value0, old_value1);
642 assert_eq!(old_value0, old_value2);
643 }
644 let actual: Vec<_> = vec.iter().cloned().collect();
645 assert_eq!(actual, baseline);
646 }
647
648 #[test]
649 #[should_panic]
650 pub fn test_swap_remove_panic() {
651 let mut vec: Vector<bool> = Vector::new(b"v".to_vec());
652 vec.swap_remove(1);
653 }
654
655 #[test]
656 #[should_panic]
657 pub fn test_swap_panic() {
658 let mut vec: Vector<bool> = Vector::new(b"v".to_vec());
659 vec.swap(1, 2);
660 }
661
662 #[test]
663 pub fn test_clear() {
664 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(3);
665 let mut vec = Vector::new(b"v".to_vec());
666 for _ in 0..100 {
667 for _ in 0..(rng.gen::<u64>() % 20 + 1) {
668 let value = rng.gen::<u64>();
669 vec.push(value);
670 }
671 assert!(!vec.is_empty());
672 vec.clear();
673 assert!(vec.is_empty());
674 }
675 }
676
677 #[test]
678 pub fn test_extend() {
679 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(0);
680 let mut vec = Vector::new(b"v".to_vec());
681 let mut baseline = vec![];
682 for _ in 0..100 {
683 let value = rng.gen::<u64>();
684 vec.push(value);
685 baseline.push(value);
686 }
687
688 for _ in 0..100 {
689 let mut tmp = vec![];
690 for _ in 0..=(rng.gen::<u64>() % 20 + 1) {
691 let value = rng.gen::<u64>();
692 tmp.push(value);
693 }
694 baseline.extend(tmp.clone());
695 vec.extend(tmp.clone());
696 }
697 let actual: Vec<_> = vec.iter().cloned().collect();
698 assert_eq!(actual, baseline);
699 }
700
701 #[test]
702 fn test_debug() {
703 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(4);
704 let prefix = b"v".to_vec();
705 let mut vec = Vector::new(prefix.clone());
706 let mut baseline = vec![];
707 for _ in 0..10 {
708 let value = rng.gen::<u64>();
709 vec.push(value);
710 baseline.push(value);
711 }
712 let actual: Vec<_> = vec.iter().cloned().collect();
713 assert_eq!(actual, baseline);
714 for _ in 0..5 {
715 assert_eq!(baseline.pop(), vec.pop());
716 }
717 if cfg!(feature = "expensive-debug") {
718 assert_eq!(format!("{:#?}", vec), format!("{:#?}", baseline));
719 } else {
720 assert_eq!(
721 format!("{:?}", vec),
722 format!("Vector {{ len: 5, prefix: {:?} }}", vec.values.prefix)
723 );
724 }
725
726 // * The storage is reused in the second part of this test, need to flush
727 vec.flush();
728
729 use unc_sdk_macros::unc;
730
731 #[unc(inside_uncsdk)]
732 #[derive(Debug)]
733 struct TestType(u64);
734
735 let deserialize_only_vec =
736 Vector::<TestType> { len: vec.len(), values: IndexMap::new(prefix) };
737 let baseline: Vec<_> = baseline.into_iter().map(TestType).collect();
738 if cfg!(feature = "expensive-debug") {
739 assert_eq!(format!("{:#?}", deserialize_only_vec), format!("{:#?}", baseline));
740 } else {
741 assert_eq!(
742 format!("{:?}", deserialize_only_vec),
743 format!("Vector {{ len: 5, prefix: {:?} }}", deserialize_only_vec.values.prefix)
744 );
745 }
746 }
747
748 #[test]
749 pub fn iterator_checks() {
750 let mut vec = Vector::new(b"v");
751 let mut baseline = vec![];
752 for i in 0..10 {
753 vec.push(i);
754 baseline.push(i);
755 }
756
757 let mut vec_iter = vec.iter();
758 let mut bl_iter = baseline.iter();
759 assert_eq!(vec_iter.next(), bl_iter.next());
760 assert_eq!(vec_iter.next_back(), bl_iter.next_back());
761 assert_eq!(vec_iter.nth(3), bl_iter.nth(3));
762 assert_eq!(vec_iter.nth_back(2), bl_iter.nth_back(2));
763
764 // Check to make sure indexing overflow is handled correctly
765 assert!(vec_iter.nth(5).is_none());
766 assert!(bl_iter.nth(5).is_none());
767
768 assert!(vec_iter.next().is_none());
769 assert!(bl_iter.next().is_none());
770
771 // Count check
772 assert_eq!(vec.iter().count(), baseline.len());
773 }
774
775 #[test]
776 pub fn iterator_mut_checks() {
777 let mut vec = Vector::new(b"v");
778 let mut baseline = vec![];
779 for i in 0..10 {
780 vec.push(i);
781 baseline.push(i);
782 }
783
784 let mut vec_iter = vec.iter_mut();
785 let mut bl_iter = baseline.iter_mut();
786 assert_eq!(vec_iter.next(), bl_iter.next());
787 assert_eq!(vec_iter.next_back(), bl_iter.next_back());
788 assert_eq!(vec_iter.nth(3), bl_iter.nth(3));
789 assert_eq!(vec_iter.nth_back(2), bl_iter.nth_back(2));
790
791 // Check to make sure indexing overflow is handled correctly
792 assert!(vec_iter.nth(5).is_none());
793 assert!(bl_iter.nth(5).is_none());
794
795 assert!(vec_iter.next().is_none());
796 assert!(bl_iter.next().is_none());
797
798 // Count check
799 assert_eq!(vec.iter().count(), baseline.len());
800 }
801
802 #[test]
803 fn drain_iterator() {
804 let mut vec = Vector::new(b"v");
805 let mut baseline = vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
806 vec.extend(baseline.clone());
807
808 assert!(Iterator::eq(vec.drain(1..=3), baseline.drain(1..=3)));
809 assert_eq!(vec.iter().copied().collect::<Vec<_>>(), vec![0, 4, 5, 6, 7, 8, 9]);
810
811 // Test incomplete drain
812 {
813 let mut drain = vec.drain(0..3);
814 let mut b_drain = baseline.drain(0..3);
815 assert_eq!(drain.next(), b_drain.next());
816 assert_eq!(drain.next(), b_drain.next());
817 assert_eq!(drain.count(), 1);
818 }
819
820 // 7 elements, drained 3
821 assert_eq!(vec.len(), 4);
822
823 // Test incomplete drain over limit
824 {
825 let mut drain = vec.drain(2..);
826 let mut b_drain = baseline.drain(2..);
827 assert_eq!(drain.next(), b_drain.next());
828 }
829
830 // Drain rest
831 assert!(Iterator::eq(vec.drain(..), baseline.drain(..)));
832
833 // Test double ended iterator functions
834 let mut vec = Vector::new(b"v");
835 let mut baseline = vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
836 vec.extend(baseline.clone());
837
838 {
839 let mut drain = vec.drain(1..8);
840 let mut b_drain = baseline.drain(1..8);
841 assert_eq!(drain.nth(1), b_drain.nth(1));
842 assert_eq!(drain.nth_back(2), b_drain.nth_back(2));
843 assert_eq!(drain.len(), b_drain.len());
844 }
845
846 assert_eq!(vec.len() as usize, baseline.len());
847 assert!(Iterator::eq(vec.iter(), baseline.iter()));
848
849 assert!(Iterator::eq(vec.drain(..), baseline.drain(..)));
850 crate::mock::with_mocked_blockchain(|m| assert!(m.take_storage().is_empty()));
851 }
852
853 #[test]
854 fn test_indexing() {
855 let mut v: Vector<i32> = Vector::new(b"b");
856 v.push(10);
857 v.push(20);
858 assert_eq!(v[0], 10);
859 assert_eq!(v[1], 20);
860 let mut x: u32 = 0;
861 assert_eq!(v[x], 10);
862 assert_eq!(v[x + 1], 20);
863 x += 1;
864 assert_eq!(v[x], 20);
865 assert_eq!(v[x - 1], 10);
866 }
867
868 #[test]
869 #[should_panic]
870 fn test_index_panic() {
871 let v: Vector<bool> = Vector::new(b"b");
872 let _ = v[1];
873 }
874
875 #[test]
876 fn test_index_mut() {
877 let mut v: Vector<i32> = Vector::new(b"b");
878 v.push(10);
879 v.push(20);
880 *v.index_mut(0) += 1;
881 assert_eq!(v[0], 11);
882 assert_eq!(v[1], 20);
883 let mut x: u32 = 0;
884 assert_eq!(v[x], 11);
885 assert_eq!(v[x + 1], 20);
886 x += 1;
887 assert_eq!(v[x], 20);
888 assert_eq!(v[x - 1], 11);
889 }
890
891 #[derive(Arbitrary, Debug)]
892 enum Op {
893 Push(u8),
894 Pop,
895 Set(u32, u8),
896 Remove(u32),
897 Flush,
898 Reset,
899 Get(u32),
900 Swap(u32, u32),
901 }
902
903 #[test]
904 #[should_panic]
905 fn test_index_mut_panic() {
906 let mut v: Vector<bool> = Vector::new(b"b");
907 v.index_mut(1);
908 }
909
910 #[test]
911 fn arbitrary() {
912 setup_free();
913
914 let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(0);
915 let mut buf = vec![0; 4096];
916 for _ in 0..1024 {
917 // Clear storage in-between runs
918 crate::mock::with_mocked_blockchain(|b| b.take_storage());
919 rng.fill_bytes(&mut buf);
920
921 let mut sv = Vector::new(b"v");
922 let mut mv = Vec::new();
923 let u = Unstructured::new(&buf);
924 if let Ok(ops) = Vec::<Op>::arbitrary_take_rest(u) {
925 for op in ops {
926 match op {
927 Op::Push(v) => {
928 sv.push(v);
929 mv.push(v);
930 assert_eq!(sv.len() as usize, mv.len());
931 }
932 Op::Pop => {
933 assert_eq!(sv.pop(), mv.pop());
934 assert_eq!(sv.len() as usize, mv.len());
935 }
936 Op::Set(k, v) => {
937 if sv.is_empty() {
938 continue;
939 }
940 let k = k % sv.len();
941
942 sv.set(k, v);
943 mv[k as usize] = v;
944
945 // Extra get just to make sure set happened correctly
946 assert_eq!(sv[k], mv[k as usize]);
947 }
948 Op::Remove(i) => {
949 if sv.is_empty() {
950 continue;
951 }
952 let i = i % sv.len();
953 let r1 = sv.swap_remove(i);
954 let r2 = mv.swap_remove(i as usize);
955 assert_eq!(r1, r2);
956 assert_eq!(sv.len() as usize, mv.len());
957 }
958 Op::Flush => {
959 sv.flush();
960 }
961 Op::Reset => {
962 let serialized = to_vec(&sv).unwrap();
963 sv = Vector::deserialize(&mut serialized.as_slice()).unwrap();
964 }
965 Op::Get(k) => {
966 let r1 = sv.get(k);
967 let r2 = mv.get(k as usize);
968 assert_eq!(r1, r2)
969 }
970 Op::Swap(i1, i2) => {
971 if sv.is_empty() {
972 continue;
973 }
974 let i1 = i1 % sv.len();
975 let i2 = i2 % sv.len();
976 sv.swap(i1, i2);
977 mv.swap(i1 as usize, i2 as usize)
978 }
979 }
980 }
981 }
982
983 // After all operations, compare both vectors
984 assert!(Iterator::eq(sv.iter(), mv.iter()));
985 }
986 }
987
988 #[test]
989 fn serialized_bytes() {
990 use borsh::{BorshDeserialize, BorshSerialize};
991
992 let mut vec = Vector::new(b"v".to_vec());
993 vec.push("Some data");
994 let serialized = to_vec(&vec).unwrap();
995
996 // Expected to serialize len then prefix
997 let mut expected_buf = Vec::new();
998 1u32.serialize(&mut expected_buf).unwrap();
999 (b"v".to_vec()).serialize(&mut expected_buf).unwrap();
1000
1001 assert_eq!(serialized, expected_buf);
1002 drop(vec);
1003 let vec = Vector::<String>::deserialize(&mut serialized.as_slice()).unwrap();
1004 assert_eq!(vec[0], "Some data");
1005 }
1006}