Struct state::Container
[−]
[src]
pub struct Container { /* fields omitted */ }
A container for global type-based state.
A container stores at most one global instance of given type as well as n thread-local instances of a given type.
Global State
Global state is set via the set method and retrieved via the
get method. The type of the value being set must be
thread-safe and transferable across thread boundaries. In other words, it
must satisfy Sync + Send + 'static
.
Example
Set and later retrieve a value of type T:
static CONTAINER: state::Container = state::Container::new(); CONTAINER.set(T::new()); CONTAINER.get::<T>();
Thread-Local State
Thread-local state is set via the set_local method and
retrieved via the get_local method. The type of the
value being set must be transferable across thread boundaries but need not
be thread-safe. In other words, it must satisfy Send + 'static
but not
necessarily Sync
. Values retrieved from thread-local state are exactly
that: local to the current thread. As such, you cannot use thread-local
state to synchronize across multiple threads.
Thread-local state is initialized on an as-needed basis. The function used
to initialize the thread-local state is passed in as an argument to
set_local
. When the state is retrieved from a given thread for the first
time, the function is executed to generate the initial value. The function
is executed at most once per thread. The same function is used for
initialization across all threads.
Note: Rust reuses thread IDs across multiple threads. This means that is possible to set thread-local state in thread A, have that thread die, start a new thread B, and access the state set in A in B.
Example
Set and later retrieve a value of type T:
static CONTAINER: state::Container = state::Container::new(); CONTAINER.set_local(|| T::new()); CONTAINER.get_local::<T>();
Methods
impl Container
[src]
const fn new() -> Container
[src]
Creates a new container with no stored values.
Example
Create a globally available state container:
static CONTAINER: state::Container = state::Container::new();
fn set<T: Send + Sync + 'static>(&self, state: T) -> bool
[src]
Sets the global state for type T
if it has not been set before.
If the state for T
has previously been set, the state is unchanged and
false
is returned. Otherwise true
is returned.
Example
Set the state for AtomicUsize
. The first set
is succesful while the
second fails.
static CONTAINER: state::Container = state::Container::new(); assert_eq!(CONTAINER.set(AtomicUsize::new(0)), true); assert_eq!(CONTAINER.set(AtomicUsize::new(1)), false);
fn try_get<T: Send + Sync + 'static>(&self) -> Option<&T>
[src]
Attempts to retrieve the global state for type T
.
Returns Some
if the state has previously been set.
Otherwise returns None
.
Example
struct MyState(AtomicUsize); static CONTAINER: state::Container = state::Container::new(); // State for `T` is initially unset. assert!(CONTAINER.try_get::<MyState>().is_none()); CONTAINER.set(MyState(AtomicUsize::new(0))); let my_state = CONTAINER.try_get::<MyState>().expect("MyState"); assert_eq!(my_state.0.load(Ordering::Relaxed), 0);
fn get<T: Send + Sync + 'static>(&self) -> &T
[src]
Retrieves the global state for type T
.
Panics
Panics if the state for type T
has not previously been
set. Use try_get for a non-panicking
version.
Example
struct MyState(AtomicUsize); static CONTAINER: state::Container = state::Container::new(); CONTAINER.set(MyState(AtomicUsize::new(0))); let my_state = CONTAINER.get::<MyState>(); assert_eq!(my_state.0.load(Ordering::Relaxed), 0);
fn set_local<T, F>(&self, state_init: F) -> bool where
T: Send + 'static,
F: Fn() -> T + 'static,
[src]
T: Send + 'static,
F: Fn() -> T + 'static,
Sets the thread-local state for type T
if it has not been set before.
The state for type T
will be initialized via the state_init
function as
needed. If the state for T
has previously been set, the state is unchanged
and false
is returned. Returns true
if the thread-local state is
successfully set to be initialized with state_init
.
Example
struct MyState(Cell<usize>); static CONTAINER: state::Container = state::Container::new(); assert_eq!(CONTAINER.set_local(|| MyState(Cell::new(1))), true); assert_eq!(CONTAINER.set_local(|| MyState(Cell::new(2))), false);
fn try_get_local<T: Send + 'static>(&self) -> Option<&T>
[src]
Attempts to retrieve the thread-local state for type T
.
Returns Some
if the state has previously been set via
set_local. Otherwise returns None
.
Example
struct MyState(Cell<usize>); static CONTAINER: state::Container = state::Container::new(); CONTAINER.set_local(|| MyState(Cell::new(10))); let my_state = CONTAINER.try_get_local::<MyState>().expect("MyState"); assert_eq!(my_state.0.get(), 10);
fn get_local<T: Send + 'static>(&self) -> &T
[src]
Retrieves the thread-local state for type T
.
Panics
Panics if the thread-local state for type T
has not previously been set
via set_local. Use
try_get_local for a non-panicking version.
Example
struct MyState(Cell<usize>); static CONTAINER: state::Container = state::Container::new(); CONTAINER.set_local(|| MyState(Cell::new(10))); let my_state = CONTAINER.get_local::<MyState>(); assert_eq!(my_state.0.get(), 10);