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()
.