pub struct SBox<T: AsDynSizeBytes + StableType> { /* private fields */ }
Expand description

Smart-pointer that allows storing any dynamic sized data on stable memory.

T should implement both StableType and AsDynSizeBytes. SBox itself implements StableType, so it will be stable-dropped automatically, when it is no longer needed. SBox also implements AsFixedSizeBytes, so you can put it in any other stable structure (e.g. SVec).

It is eager on writes, but lazy on reads. When you create or update it, the underlying value gets immediately serialized and written to stable memory, but when you read it after it was stored in some other stable data structure, it’s underlying value gets read and deserialized only when you access it.

You can access the underlying data by dereferencing it, for immutable access. For mutable access you have to use SBox::with method (similar to thread_local!’s with() method).

Examples

{
    let mut boxed_string = SBox::new(String::from("Test string"))
        .expect("Out of memory");

    assert_eq!(&*boxed_string, "Test string");

    boxed_string.with(|it| {
        *it = String::from("Much much longer test string");
    }).expect("Out of memory");

    assert_eq!(&*boxed_string, "Much much longer test string");
} // <- gets stable-dropped here automatically

Implementations§

source§

impl<T: AsDynSizeBytes + StableType> SBox<T>

source

pub fn new(it: T) -> Result<Self, T>

Stores dynamic sized data on stable memory, immediately serializing and allocating.

Returns Err and the data, if the canister is OutOfMemory.

source

pub fn as_ptr(&self) -> u64

Returns a pointer to the underlying SSlice of stable memory.

See also SBox::from_ptr.

source

pub fn into_inner(self) -> T

Returns the underlying data, releasing occupied stable memory.

source

pub unsafe fn from_ptr(ptr: u64) -> Self

Creates SBox from a pointer to the underlying SSlice of stable memory.

See also SBox::as_ptr.

Panics

Panics if the pointer points to an invalid (or free) block of stable memory.

Safety

This method basically allows you to clone the smart-pointer, which breaks ownership and stable-drop rules. Always make sure you restore stable-drop rules manually. Always destroy other copies of the same SBox before mutating it or the underlying data.

Example
let mut b = SBox::new(10u64).expect("Out of memory");
unsafe { b.stable_drop_flag_off() };

b = unsafe { SBox::from_ptr(b.as_ptr()) };
source

pub fn with<R, F: FnOnce(&mut T) -> R>( &mut self, func: F ) -> Result<R, OutOfMemory>

Provides mutable access to the underlying data, by accepting a lambda function.

Returns OutOfMemory error if it was impossible to reallocate the underlying SSlice to make it bugger.

Example

#[derive(CandidType, Deserialize, CandidAsDynSizeBytes, StableType, Debug)]
struct A {
    name: String,
    id: u64,
}

let it = A { name: String::from("Sasha"), id: 1 };
let mut b = SBox::new(it).expect("Out of memory");

b.with(|it| it.id += 1).unwrap();

Trait Implementations§

source§

impl<T: AsDynSizeBytes + StableType> AsFixedSizeBytes for SBox<T>

source§

const SIZE: usize = 8usize

Size of self when encoded
§

type Buf = [u8; 8]

Buffer that is used to encode this value into
source§

fn as_fixed_size_bytes(&self, buf: &mut [u8])

Encodes itself into a slice of bytes. Read more
source§

fn from_fixed_size_bytes(arr: &[u8]) -> Self

Decodes itself from a slice of bytes. Read more
source§

fn as_new_fixed_size_bytes(&self) -> Self::Buf

Encodes itself into a new Self::Buf of size == Self::SIZE
source§

impl<T: AsHashTree + AsDynSizeBytes + StableType> AsHashTree for SBox<T>

source§

fn root_hash(&self) -> Hash

Returns the root hash of the tree without constructing it. Must be equivalent to [HashTree::reconstruct].
source§

fn hash_tree(&self) -> HashTree

Returns a [HashTree] of this value. Must be equivalent to AsHashTree::root_hash.
source§

impl<T: AsDynSizeBytes + StableType> Borrow<T> for SBox<T>

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T: Debug + AsDynSizeBytes + StableType> Debug for SBox<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: AsDynSizeBytes + StableType> Deref for SBox<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T: AsDynSizeBytes + StableType> Drop for SBox<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<T: Hash + AsDynSizeBytes + StableType> Hash for SBox<T>

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T: Ord + PartialOrd + AsDynSizeBytes + StableType> Ord for SBox<T>

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere Self: Sized + PartialOrd<Self>,

Restrict a value to a certain interval. Read more
source§

impl<T: PartialEq + AsDynSizeBytes + StableType> PartialEq<SBox<T>> for SBox<T>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd + AsDynSizeBytes + StableType> PartialOrd<SBox<T>> for SBox<T>

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl<T: AsDynSizeBytes + StableType> StableType for SBox<T>

source§

fn should_stable_drop(&self) -> bool

Should return the value of the stable drop flag
source§

unsafe fn stable_drop_flag_off(&mut self)

Sets stable drop flag to off position, if it is applicable Read more
source§

unsafe fn stable_drop_flag_on(&mut self)

Should set stable drop flag to on position, if it is applicable Read more
source§

unsafe fn stable_drop(&mut self)

Performs stable drop, releasing all underlying stable memory of this data structure Read more
source§

impl<T: AsHashableBytes + AsDynSizeBytes + StableType> AsHashableBytes for SBox<T>

source§

impl<T: Eq + PartialEq + AsDynSizeBytes + StableType> Eq for SBox<T>

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for SBox<T>

§

impl<T> Send for SBox<T>where T: Send,

§

impl<T> !Sync for SBox<T>

§

impl<T> Unpin for SBox<T>where T: Unpin,

§

impl<T> UnwindSafe for SBox<T>where T: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> AsDynSizeBytes for Twhere T: AsFixedSizeBytes,

source§

fn as_dyn_size_bytes(&self) -> Vec<u8, Global>

Encodes self into vector of bytes Read more
source§

fn from_dyn_size_bytes(buf: &[u8]) -> T

Decodes self from a slice of bytes. Read more
source§

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

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

const: unstable · source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

const: unstable · 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<T> for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.
source§

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

§

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

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.