ic_storage/adapter/
cell.rs1use super::{
3 Bound, Memory, Storable,
4 bridge::{self, Backing, Codec},
5 error::{CollectionError as Error, Result, ensure},
6};
7use crate::{DefaultMemoryImpl, RuntimeMemory, engine};
8
9pub struct StableCell<T: Storable, M: Memory = DefaultMemoryImpl> {
16 inner: engine::cell::Cell<Codec<T>, Backing<RuntimeMemory<M>>>,
17}
18impl<T: Storable, M: Memory> StableCell<T, M> {
19 pub fn create(memory: RuntimeMemory<M>, value: T) -> Result<Self> {
23 ensure(memory.size() == 0, Error::NotEmpty)?;
24 Self::reset(memory, value)
25 }
26 pub fn reset(memory: RuntimeMemory<M>, value: T) -> Result<Self> {
30 bridge::reserve(&memory)?;
31 #[cfg(not(target_arch = "wasm32"))]
32 let _guard = memory.poison_on_unwind();
33 Ok(Self {
34 inner: engine::cell::Cell::new(Backing(memory), Codec(value)),
35 })
36 }
37 pub fn load(memory: RuntimeMemory<M>, maximum: usize) -> Result<Self> {
43 let maximum = match T::BOUND {
44 Bound::Bounded { max_size, .. } => maximum.min(max_size as usize),
45 Bound::Unbounded => maximum,
46 };
47 let length = crate::stable_cell_payload_length(&memory, maximum)?;
48 Ok(Self {
49 inner: engine::cell::Cell::load_with_length(
50 Backing(memory),
51 u32::try_from(length).expect("admitted cell length"),
52 ),
53 })
54 }
55 pub const fn get(&self) -> &T {
57 &self.inner.get().0
58 }
59 pub fn set(&mut self, value: T) -> Result<T> {
63 #[cfg(not(target_arch = "wasm32"))]
64 let _guard = self.inner.memory().0.poison_on_unwind();
65 Ok(self.inner.set(Codec(value)).0)
66 }
67}