Skip to main content

InMemory

Struct InMemory 

Source
pub struct InMemory<C> { /* private fields */ }
Expand description

Transient, cell-local storage for state that must not be persisted, such as host resource handles (sockets, subscriptions, scan sessions, …) held across handler invocations.

Unlike State, InMemory never touches the data layer: the wrapped value only lives for as long as the cell instance is loaded and is lost on restart. It is typically stored in a static and accessed through InMemory::with.

Wrap the value in an Option and declare it with InMemory::empty when it only becomes available at runtime, such as a handle returned by a host call.

Implementations§

Source§

impl<C> InMemory<C>

Source

pub const fn new(value: C) -> Self

Wraps value in a new InMemory.

Source

pub fn with<R>(&self, f: impl FnOnce(&mut C) -> R) -> Result<R>

Runs f with mutable access to the wrapped value.

This covers the common case of reading or updating the value in a single expression. If you need to interleave the access with control flow in the caller, such as an early return, a return inside f only exits f itself; use InMemory::try_borrow_mut or InMemory::try_borrow instead, since the guard they return lives in the caller’s own scope.

§Errors

Returns an error if with is called re-entrantly, i.e. from within another call to with/upsert_with/try_borrow/try_borrow_mut on the same InMemory (for example, from a callback invoked by f).

Source

pub fn try_borrow(&self) -> Result<Ref<'_, C>>

Immutably borrows the wrapped value.

Prefer this over InMemory::with when the access needs to be interleaved with control flow in the caller, since the returned guard lives in the caller’s own scope rather than inside a closure.

§Errors

Returns an error if the value is currently mutably borrowed, i.e. from a re-entrant call to with/upsert_with/try_borrow_mut (for example, from within a callback).

Source

pub fn try_borrow_mut(&self) -> Result<RefMut<'_, C>>

Mutably borrows the wrapped value.

Prefer this over InMemory::with when the access needs to be interleaved with control flow in the caller, since the returned guard lives in the caller’s own scope rather than inside a closure.

§Errors

Returns an error if the value is already borrowed, i.e. from a re-entrant call to with/upsert_with/try_borrow/try_borrow_mut (for example, from within a callback).

Source§

impl<T> InMemory<Option<T>>

Source

pub const fn empty() -> Self

Declares a InMemory that starts out without a value.

Use this for a value that can only be built at runtime, such as a handle returned by a host call. The Option is part of the stored type, so InMemory::with hands the closure an &mut Option<T> and the caller deals with exactly one level of optionality:

static SCAN: InMemory<Option<ScanHandle>> = InMemory::empty();

SCAN.with(|slot| *slot = Some(scan))?;

if let Some(scan) = SCAN.with(Option::take)? {
    scan.stop()?;
}

When T implements Default, InMemory::upsert_with hands the closure an &mut T instead, inserting the default value first.

Source§

impl<T> InMemory<Option<T>>
where T: Default,

Source

pub fn upsert_with<R>(&self, f: impl FnOnce(&mut T) -> R) -> Result<R>

Runs f with mutable access to the wrapped value, inserting T::default() first if there is no value yet.

This mirrors the upsert family on State for a value that is never persisted. Since the insert guarantees a value, f receives an &mut T and its result is not wrapped in an Option, which makes this the more direct way to build a value up field by field across several invocations:

static SESSION: InMemory<Option<Session>> = InMemory::empty();

SESSION.upsert_with(|session| session.scan = Some(scan))?;
§Errors

Returns an error if upsert_with is called re-entrantly, i.e. from within another call to with/upsert_with/try_borrow/try_borrow_mut on the same InMemory (for example, from a callback invoked by f).

Trait Implementations§

Source§

impl<C> Sync for InMemory<C>

Auto Trait Implementations§

§

impl<C> !Freeze for InMemory<C>

§

impl<C> !RefUnwindSafe for InMemory<C>

§

impl<C> Send for InMemory<C>
where RefCell<C>: Send,

§

impl<C> Unpin for InMemory<C>
where RefCell<C>: Unpin,

§

impl<C> UnsafeUnpin for InMemory<C>
where RefCell<C>: UnsafeUnpin,

§

impl<C> UnwindSafe for InMemory<C>
where RefCell<C>: 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.