ic_storage/adapter/
vector.rs1use super::{
3 Memory, Storable,
4 bridge::{self, Backing, Codec},
5 error::{CollectionError as Error, Result, ensure},
6};
7use crate::{DefaultMemoryImpl, RuntimeMemory, engine};
8
9pub struct StableVec<T: Storable, M: Memory = DefaultMemoryImpl> {
17 inner: engine::vec::Vec<Codec<T>, Backing<RuntimeMemory<M>>>,
18}
19impl<T: Storable, M: Memory> StableVec<T, M> {
20 pub fn create(memory: RuntimeMemory<M>) -> Result<Self> {
24 ensure(memory.size() == 0, Error::NotEmpty)?;
25 Self::reset(memory)
26 }
27 pub fn reset(memory: RuntimeMemory<M>) -> Result<Self> {
31 bridge::reserve(&memory)?;
32 #[cfg(not(target_arch = "wasm32"))]
33 let _guard = memory.poison_on_unwind();
34 Ok(Self {
35 inner: engine::vec::Vec::new(Backing(memory)),
36 })
37 }
38 pub fn load(memory: RuntimeMemory<M>) -> Result<Self> {
42 ensure(memory.size() != 0, Error::Format)?;
43 let mut marker = [0; 4];
44 memory.read(0, &mut marker);
45 ensure(&marker == b"SVC\x01", Error::Format)?;
46 Ok(Self {
47 inner: engine::vec::Vec::init(Backing(memory)),
48 })
49 }
50 pub fn get(&self, index: u64) -> Result<Option<T>> {
54 Ok(self.inner.get(index).map(|v| v.0))
55 }
56 pub fn set(&self, index: u64, item: &T) -> Result<()> {
60 #[cfg(not(target_arch = "wasm32"))]
61 let _guard = self.inner.memory().0.poison_on_unwind();
62 self.inner.set(index, Codec::borrowed(item));
63 Ok(())
64 }
65 pub fn push(&self, item: &T) -> Result<()> {
69 #[cfg(not(target_arch = "wasm32"))]
70 let _guard = self.inner.memory().0.poison_on_unwind();
71 self.inner.push(Codec::borrowed(item));
72 Ok(())
73 }
74 pub fn pop(&self) -> Result<Option<T>> {
78 #[cfg(not(target_arch = "wasm32"))]
79 let _guard = self.inner.memory().0.poison_on_unwind();
80 Ok(self.inner.pop().map(|v| v.0))
81 }
82 #[must_use]
84 pub fn len(&self) -> u64 {
85 self.inner.len()
86 }
87 #[must_use]
89 pub fn is_empty(&self) -> bool {
90 self.inner.is_empty()
91 }
92 pub fn iter(&self) -> impl DoubleEndedIterator<Item = Result<T>> + '_ {
94 Iter(self.inner.iter())
95 }
96}
97
98struct Iter<I>(I);
101impl<T, I: Iterator<Item = Codec<T>>> Iterator for Iter<I> {
102 type Item = Result<T>;
103 fn next(&mut self) -> Option<Self::Item> {
104 self.0.next().map(|v| Ok(v.0))
105 }
106 fn nth(&mut self, n: usize) -> Option<Self::Item> {
107 self.0.nth(n).map(|v| Ok(v.0))
108 }
109 fn count(self) -> usize {
110 self.0.count()
111 }
112 fn last(self) -> Option<Self::Item> {
113 self.0.last().map(|v| Ok(v.0))
114 }
115 fn size_hint(&self) -> (usize, Option<usize>) {
116 self.0.size_hint()
117 }
118}
119impl<T, I: DoubleEndedIterator<Item = Codec<T>>> DoubleEndedIterator for Iter<I> {
120 fn next_back(&mut self) -> Option<Self::Item> {
121 self.0.next_back().map(|v| Ok(v.0))
122 }
123 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
124 self.0.nth_back(n).map(|v| Ok(v.0))
125 }
126}
127#[cfg(all(test, not(target_arch = "wasm32")))]
130mod tests;