ic_storage/adapter/
vector.rs1use super::{
3 Memory, Storable,
4 bridge::{self, Codec},
5 error::{CollectionError as Error, Result, ensure},
6};
7use crate::engine::vec::InitError;
8use crate::{DefaultMemoryImpl, RuntimeMemory, engine};
9
10pub struct StableVec<T: Storable, M: Memory = DefaultMemoryImpl> {
18 inner: engine::vec::Vec<Codec<T>, RuntimeMemory<M>>,
19}
20impl<T: Storable, M: Memory> StableVec<T, M> {
21 pub fn create(memory: RuntimeMemory<M>) -> Result<Self> {
25 ensure(memory.size() == 0, Error::NotEmpty)?;
26 Self::reset(memory)
27 }
28 pub fn reset(memory: RuntimeMemory<M>) -> Result<Self> {
32 bridge::reserve(&memory)?;
33 #[cfg(not(target_arch = "wasm32"))]
34 let _guard = memory.poison_on_unwind();
35 Ok(Self {
36 inner: engine::vec::Vec::new(memory),
37 })
38 }
39 pub fn load(memory: RuntimeMemory<M>) -> Result<Self> {
45 ensure(memory.size() != 0, Error::Format)?;
46 let inner = match engine::vec::Vec::init(memory) {
47 Ok(vector) => vector,
48 Err(InitError::BadMagic { .. } | InitError::IncompatibleVersion(_)) => {
49 return Err(Error::Format);
50 }
51 Err(error) => panic!("Failed to initialize a vector: {error:?}"),
52 };
53 Ok(Self { inner })
54 }
55 #[must_use]
57 pub fn get(&self, index: u64) -> Option<T> {
58 self.inner.get(index).map(|v| v.0)
59 }
60 pub fn set(&self, index: u64, item: &T) {
62 #[cfg(not(target_arch = "wasm32"))]
63 let _guard = self.inner.memory().poison_on_unwind();
64 self.inner.set(index, Codec::borrowed(item));
65 }
66 pub fn push(&self, item: &T) {
68 #[cfg(not(target_arch = "wasm32"))]
69 let _guard = self.inner.memory().poison_on_unwind();
70 self.inner.push(Codec::borrowed(item));
71 }
72 #[must_use]
74 pub fn pop(&self) -> Option<T> {
75 #[cfg(not(target_arch = "wasm32"))]
76 let _guard = self.inner.memory().poison_on_unwind();
77 self.inner.pop().map(|v| v.0)
78 }
79 #[must_use]
81 pub fn len(&self) -> u64 {
82 self.inner.len()
83 }
84 #[must_use]
86 pub fn is_empty(&self) -> bool {
87 self.inner.is_empty()
88 }
89 pub fn iter(&self) -> impl DoubleEndedIterator<Item = T> + '_ {
92 Iter(self.inner.iter())
93 }
94}
95
96struct Iter<I>(I);
99impl<T, I: Iterator<Item = Codec<T>>> Iterator for Iter<I> {
100 type Item = T;
101 fn next(&mut self) -> Option<Self::Item> {
102 self.0.next().map(|v| v.0)
103 }
104 fn nth(&mut self, n: usize) -> Option<Self::Item> {
105 self.0.nth(n).map(|v| v.0)
106 }
107 fn count(self) -> usize {
108 self.0.count()
109 }
110 fn last(self) -> Option<Self::Item> {
111 self.0.last().map(|v| v.0)
112 }
113 fn size_hint(&self) -> (usize, Option<usize>) {
114 self.0.size_hint()
115 }
116}
117impl<T, I: DoubleEndedIterator<Item = Codec<T>>> DoubleEndedIterator for Iter<I> {
118 fn next_back(&mut self) -> Option<Self::Item> {
119 self.0.next_back().map(|v| v.0)
120 }
121 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
122 self.0.nth_back(n).map(|v| v.0)
123 }
124}
125#[cfg(all(test, not(target_arch = "wasm32")))]
128mod tests;