pub struct TakeOnce<T> { /* private fields */ }Expand description
A thread-safe container that allows storing a value once and taking it exactly once. This is useful in scenarios where:
- A value needs to be initialized lazily but only once
- The initialized value should be consumable (moved out) rather than just accessible.
See
std::sync::OnceLockfor a similar use case where the value can be accessed in place. - Multiple threads might attempt to initialize or consume the value, but only one should succeed
§Thread Safety
TakeOnce<T> implements Send and Sync when T: Send, making it safe to share
across thread boundaries. All operations are atomic and properly synchronized.
§Memory Management
The stored value is heap-allocated and properly cleaned up when the TakeOnce is dropped.
§Examples
Basic usage:
use take_once::TakeOnce;
let cell = TakeOnce::new();
// Initial store succeeds
assert_eq!(cell.store(42), Ok(()));
// Subsequent stores return the provided value
assert_eq!(cell.store(24), Err(24));
// Take the value
assert_eq!(cell.take(), Some(42));
// Can't take twice
assert_eq!(cell.take(), None);Concurrent usage:
use std::sync::Arc;
use std::thread;
use take_once::TakeOnce;
let shared = Arc::new(TakeOnce::new());
let threads: Vec<_> = (0..3)
.map(|i| {
let shared = shared.clone();
thread::spawn(move || {
// Only one thread will successfully store
shared.store(i)
})
})
.collect();Implementations§
Source§impl<T> TakeOnce<T>
impl<T> TakeOnce<T>
Sourcepub fn new_with(val: T) -> TakeOnce<T>
pub fn new_with(val: T) -> TakeOnce<T>
Create and store a cell in a single operation
use take_once::TakeOnce;
let initialized = TakeOnce::new_with(true);
assert_eq!(initialized.store(false), Err(false));
assert_eq!(initialized.take(), Some(true));Sourcepub fn take(&self) -> Option<T>
pub fn take(&self) -> Option<T>
Takes the value out of this TakeOnce, if it has been initialized.
If the TakeOnce has not been initialized, or if the value has already been taken,
this method returns None.
Sourcepub fn is_completed(&self) -> bool
pub fn is_completed(&self) -> bool
Returns true if the value has been initialized, regardless of whether it has been taken.
In other words, this returns true if store has been called at least once.