shared_framework/utils/atom.rs
1//! Shared optional value holder.
2//!
3//! [`AtomHolder<T>`] is a cheaply clonable, thread-safe container for an
4//! optional value of type `T`. Clones share the same slot: [`set`](AtomHolder::set)
5//! from one clone is visible via [`get`](AtomHolder::get) on the others.
6//!
7//! ```ignore
8//! let holder = AtomHolder::new();
9//! holder.set(42);
10//! assert_eq!(holder.get(), Some(42));
11//! assert_eq!(holder.take(), Some(42));
12//! assert_eq!(holder.get(), None);
13//! ```
14use std::sync::{Arc, Mutex};
15
16/// Thread-safe holder for an optional value of type `T`. Clones share one slot.
17#[derive(Clone)]
18pub struct AtomHolder<T: Clone> {
19 inner: Arc<Mutex<Option<T>>>,
20}
21
22impl<T: Clone> AtomHolder<T> {
23 /// Creates an empty holder.
24 pub fn new() -> Self { Self { inner: Arc::new(Mutex::new(None)) } }
25 /// Replaces the stored value.
26 pub fn set(&self, v: T) { *self.inner.lock().unwrap() = Some(v); }
27 /// Returns a clone of the stored value, if any.
28 pub fn get(&self) -> Option<T> { self.inner.lock().unwrap().clone() }
29 /// Removes and returns the stored value, leaving the holder empty.
30 pub fn take(&self) -> Option<T> { self.inner.lock().unwrap().take() }
31}
32
33impl<T: Clone> Default for AtomHolder<T> {
34 fn default() -> Self { Self::new() }
35}