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>
impl<T> InitCell<T>
sourcepub const fn new() -> InitCell<T>
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();sourcepub fn set(&self, value: T) -> bool
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);sourcepub fn reset(&mut self)
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());sourcepub fn get_or_init<F: FnOnce() -> T>(&self, f: F) -> &T
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!");sourcepub fn wait(&self) -> &T
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!");sourcepub fn try_get(&self) -> Option<&T>
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!"));sourcepub fn try_get_mut(&mut self) -> Option<&mut T>
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());sourcepub fn get(&self) -> &T
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!");sourcepub fn take(&mut self) -> Option<T>
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);sourcepub fn into_inner(self) -> Option<T>
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());sourcepub fn update<F: FnOnce(T) -> T>(&mut self, f: F)
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());sourcepub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> InitCell<U>
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> Default for InitCell<T>
impl<T> Default for InitCell<T>
Defaults to InitCell::new().