Cell

Struct Cell 

Source
pub struct Cell<T, M>
where T: Storable, M: Memory,
{ /* private fields */ }
Expand description

Represents a value stored in stable memory.

A Cell stores a single value directly in stable memory and provides immediate persistence on every write operation. This makes it ideal for configuration values, metadata, or any small state that needs to survive canister upgrades.

You should use cells only for small (up to a few MiB) values to keep upgrades safe. For larger values, consider using other data structures like Vec or BTreeMap instead.

§Example

use ic_stable_structures::{Cell, DefaultMemoryImpl, Storable, storable::Bound};
use std::borrow::Cow;
use std::cell::RefCell;

#[derive(Clone)]
struct Config {
    name: String,
    version: u32,
}

// Implement Storable for serialization/deserialization when saving to stable memory.
impl Storable for Config {
    fn to_bytes(&self) -> Cow<'_, [u8]> {
        // Convert config into bytes...
    }

    fn into_bytes(self) -> Vec<u8> {
        // Convert config into bytes...
    }

    fn from_bytes(bytes: Cow<[u8]>) -> Self {
        // Convert bytes back to Config
    }

    // Types can be bounded or unbounded:
    // - Use Bound::Unbounded if the size can vary or isn't known in advance (recommended for most cases)
    // - Use Bound::Bounded if you know the maximum size and want memory optimization
    const BOUND: Bound = Bound::Unbounded;
}

// Create a global cell variable
thread_local! {
    static CONFIG: RefCell<Cell<Config, DefaultMemoryImpl>> = RefCell::new(
        Cell::init(
            DefaultMemoryImpl::default(),
            Config {
                name: "MyConfig".to_string(),
                version: 1,
            }
        )
    );
}

// Read the current configuration
fn get_version() -> u32 {
    CONFIG.with(|c| c.borrow().get().version)
}

// Update the configuration
fn update_version(new_version: u32) {
    CONFIG.with(|c| {
        let mut cell = c.borrow_mut();
        let mut config = cell.get().clone();
        config.version = new_version;
        cell.set(config);
    });
}

Implementations§

Source§

impl<T, M> Cell<T, M>
where T: Storable, M: Memory,

Source

pub fn new(memory: M, value: T) -> Cell<T, M>

Creates a new cell in the specified memory, overwriting the previous contents of the memory.

Source

pub fn init(memory: M, default_value: T) -> Cell<T, M>

Initializes the value of the cell based on the contents of the memory. If the memory already contains a cell, initializes the cell with the decoded value. Otherwise, sets the cell value to default_value and writes it to the memory.

Source

pub fn get(&self) -> &T

Returns the current value in the cell.

Source

pub fn into_memory(self) -> M

Returns the underlying memory.

Source

pub fn set(&mut self, value: T) -> T

Updates the current value in the cell. If the new value is too large to fit into the memory, the value in the cell does not change.

Auto Trait Implementations§

§

impl<T, M> Freeze for Cell<T, M>
where M: Freeze, T: Freeze,

§

impl<T, M> RefUnwindSafe for Cell<T, M>

§

impl<T, M> Send for Cell<T, M>
where M: Send, T: Send,

§

impl<T, M> Sync for Cell<T, M>
where M: Sync, T: Sync,

§

impl<T, M> Unpin for Cell<T, M>
where M: Unpin, T: Unpin,

§

impl<T, M> UnwindSafe for Cell<T, M>
where M: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.