Skip to main content

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}