Struct ic_stable_memory::primitive::s_box::SBox
source · 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 automaticallyImplementations§
source§impl<T: AsDynSizeBytes + StableType> SBox<T>
impl<T: AsDynSizeBytes + StableType> SBox<T>
sourcepub fn new(it: T) -> Result<Self, T>
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.
sourcepub fn as_ptr(&self) -> u64
pub fn as_ptr(&self) -> u64
Returns a pointer to the underlying SSlice of stable memory.
See also SBox::from_ptr.
sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Returns the underlying data, releasing occupied stable memory.
sourcepub unsafe fn from_ptr(ptr: u64) -> Self
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()) };sourcepub fn with<R, F: FnOnce(&mut T) -> R>(
&mut self,
func: F
) -> Result<R, OutOfMemory>
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>
impl<T: AsDynSizeBytes + StableType> AsFixedSizeBytes for SBox<T>
source§fn as_fixed_size_bytes(&self, buf: &mut [u8])
fn as_fixed_size_bytes(&self, buf: &mut [u8])
source§fn from_fixed_size_bytes(arr: &[u8]) -> Self
fn from_fixed_size_bytes(arr: &[u8]) -> Self
source§fn as_new_fixed_size_bytes(&self) -> Self::Buf
fn as_new_fixed_size_bytes(&self) -> Self::Buf
source§impl<T: AsHashTree + AsDynSizeBytes + StableType> AsHashTree for SBox<T>
impl<T: AsHashTree + AsDynSizeBytes + StableType> AsHashTree for SBox<T>
source§impl<T: AsDynSizeBytes + StableType> Borrow<T> for SBox<T>
impl<T: AsDynSizeBytes + StableType> Borrow<T> for SBox<T>
source§impl<T: Debug + AsDynSizeBytes + StableType> Debug for SBox<T>
impl<T: Debug + AsDynSizeBytes + StableType> Debug for SBox<T>
source§impl<T: AsDynSizeBytes + StableType> Deref for SBox<T>
impl<T: AsDynSizeBytes + StableType> Deref for SBox<T>
source§impl<T: AsDynSizeBytes + StableType> Drop for SBox<T>
impl<T: AsDynSizeBytes + StableType> Drop for SBox<T>
source§impl<T: Hash + AsDynSizeBytes + StableType> Hash for SBox<T>
impl<T: Hash + AsDynSizeBytes + StableType> Hash for SBox<T>
source§impl<T: Ord + PartialOrd + AsDynSizeBytes + StableType> Ord for SBox<T>
impl<T: Ord + PartialOrd + AsDynSizeBytes + StableType> Ord for SBox<T>
source§impl<T: PartialEq + AsDynSizeBytes + StableType> PartialEq<SBox<T>> for SBox<T>
impl<T: PartialEq + AsDynSizeBytes + StableType> PartialEq<SBox<T>> for SBox<T>
source§impl<T: PartialOrd + AsDynSizeBytes + StableType> PartialOrd<SBox<T>> for SBox<T>
impl<T: PartialOrd + AsDynSizeBytes + StableType> PartialOrd<SBox<T>> for SBox<T>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self and other) and is used by the <=
operator. Read moresource§impl<T: AsDynSizeBytes + StableType> StableType for SBox<T>
impl<T: AsDynSizeBytes + StableType> StableType for SBox<T>
source§fn should_stable_drop(&self) -> bool
fn should_stable_drop(&self) -> bool
source§unsafe fn stable_drop_flag_off(&mut self)
unsafe fn stable_drop_flag_off(&mut self)
off position, if it is applicable Read moresource§unsafe fn stable_drop_flag_on(&mut self)
unsafe fn stable_drop_flag_on(&mut self)
on position, if it is applicable Read more