Struct state::InitCell

source ·
pub struct InitCell<T> { /* private fields */ }
Expand description

An init-once cell for global access to a value.

A InitCell instance can hold a single value in a global context. A InitCell instance begins without a value and must be initialized via the set() method. Once a value has been set, it can be retrieved at any time and in any thread via the get() method. The try_get() can be used to determine whether the InitCell has been initialized before attempting to retrieve the value.

Example

The following example uses InitCell to hold a global instance of a HashMap which can be modified at will:

use std::collections::HashMap;
use std::sync::Mutex;
use std::thread;

use state::InitCell;

static GLOBAL_MAP: InitCell<Mutex<HashMap<String, String>>> = InitCell::new();

fn run_program() {
    let mut map = GLOBAL_MAP.get().lock().unwrap();
    map.insert("another_key".into(), "another_value".into());
}

fn main() {
    // Create the initial map and store it in `GLOBAL_MAP`.
    let mut initial_map = HashMap::new();
    initial_map.insert("key".into(), "value".into());
    GLOBAL_MAP.set(Mutex::new(initial_map));

    // For illustration, we spawn a new thread that modified the map.
    thread::spawn(|| run_program()).join().expect("thread");

    // Assert that the modification took place.
    let map = GLOBAL_MAP.get().lock().unwrap();
    assert_eq!(map.get("another_key").unwrap(), "another_value");
}

Implementations§

source§

impl<T> InitCell<T>

source

pub const fn new() -> InitCell<T>

Create a new, uninitialized cell.

To create a cell initializd with a value, use InitCell::from().

Example
use state::InitCell;

static MY_GLOBAL: InitCell<String> = InitCell::new();
source

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

Sets this cell’s value to value if it is not already initialized.

If there are multiple simultaneous callers, exactly one is guaranteed to receive true, indicating its value was set. All other callers receive false, indicating the value was ignored.

Example
static MY_GLOBAL: InitCell<&'static str> = InitCell::new();

assert_eq!(MY_GLOBAL.set("Hello, world!"), true);
assert_eq!(MY_GLOBAL.set("Goodbye, world!"), false);
source

pub fn reset(&mut self)

Resets the cell to an uninitialized state.

Example
use state::InitCell;

let mut cell = InitCell::from(5);
assert_eq!(cell.get(), &5);

cell.reset();
assert!(cell.try_get().is_none());
source

pub fn get_or_init<F: FnOnce() -> T>(&self, f: F) -> &T

If the cell is not initialized, it is set f(). Returns a borrow to the value in this cell.

If f() panics during initialization, the cell is left uninitialized.

Example
static MY_GLOBAL: InitCell<&'static str> = InitCell::new();

assert_eq!(*MY_GLOBAL.get_or_init(|| "Hello, world!"), "Hello, world!");
source

pub fn wait(&self) -> &T

Waits (blocks) until the cell has a value and then borrows it.

Example
static MY_GLOBAL: InitCell<&'static str> = InitCell::new();

MY_GLOBAL.set("Hello, world!");
assert_eq!(*MY_GLOBAL.get(), "Hello, world!");
source

pub fn try_get(&self) -> Option<&T>

Get a reference to the underlying value, if one is set.

Returns Some if the state has previously been set via methods like InitCell::set() or InitCell::get_or_init(). Otherwise returns None.

Example
static MY_GLOBAL: InitCell<&'static str> = InitCell::new();

assert_eq!(MY_GLOBAL.try_get(), None);

MY_GLOBAL.set("Hello, world!");

assert_eq!(MY_GLOBAL.try_get(), Some(&"Hello, world!"));
source

pub fn try_get_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the underlying data if any is set.

This call borrows InitCell mutably (at compile-time) so there is no need for dynamic checks.

Example
use state::InitCell;

let mut cell = InitCell::from(5);
*cell.try_get_mut().unwrap() += 1;

let mut cell: InitCell<usize> = InitCell::new();
assert!(cell.try_get_mut().is_none());
source

pub fn get(&self) -> &T

Borrows the value in this cell, panicking if there is no value.

Panics

Panics if a value has not previously been set(). Use try_get() for a non-panicking version.

Example
static MY_GLOBAL: InitCell<&'static str> = InitCell::new();

MY_GLOBAL.set("Hello, world!");
assert_eq!(*MY_GLOBAL.get(), "Hello, world!");
source

pub fn take(&mut self) -> Option<T>

Resets the cell to an uninitialized state and returns the inner value if any was set.

Example
use state::InitCell;

let mut cell = InitCell::from(5);
assert_eq!(cell.get(), &5);
assert_eq!(cell.get(), &5);

assert_eq!(cell.take(), Some(5));
assert_eq!(cell.take(), None);
source

pub fn into_inner(self) -> Option<T>

Returns the inner value if any is set.

Example
use state::InitCell;

let cell = InitCell::from(5);
assert_eq!(cell.into_inner().unwrap(), 5);

let cell: InitCell<usize> = InitCell::new();
assert!(cell.into_inner().is_none());
source

pub fn update<F: FnOnce(T) -> T>(&mut self, f: F)

Applies the function f to the inner value, if there is any, leaving the updated value in the cell.

If f() panics during updating, the cell is left uninitialized.

Example
use state::InitCell;

let mut cell = InitCell::from(5);
cell.update(|v| v + 10);
assert_eq!(cell.wait(), &15);

let mut cell = InitCell::new();
cell.update(|v: u8| v + 10);
assert!(cell.try_get().is_none());
source

pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> InitCell<U>

Applies the function f to the inner value, if there is any, and returns a new InitCell with mapped value.

Example
use state::InitCell;

let cell = InitCell::from(5);
assert_eq!(cell.get(), &5);

let cell = cell.map(|v| v + 10);
assert_eq!(cell.get(), &15);

Trait Implementations§

source§

impl<T: Clone> Clone for InitCell<T>

source§

fn clone(&self) -> InitCell<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for InitCell<T>

source§

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

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

impl<T> Default for InitCell<T>

Defaults to InitCell::new().

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<T> From<T> for InitCell<T>

source§

fn from(value: T) -> InitCell<T>

Converts to this type from the input type.
source§

impl<T: Send> Send for InitCell<T>

source§

impl<T: Send + Sync> Sync for InitCell<T>

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for InitCell<T>

§

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

§

impl<T> UnwindSafe for InitCell<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> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<!> for T

source§

fn from(t: !) -> T

Converts to this type from the input type.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere 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> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

§

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 Twhere U: TryFrom<T>,

§

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.