arc_atomic_ref/
lib.rs

1//! # arc-atomic-ref
2//!
3//! an `AtomicRef` is a smart pointer type that can be shared with many
4//! different threads of execution, while at the same time can be swapped out
5//! atomically with new data. In this way, it's similar to a lock-free
6//! `RwLock` or `Mutex` when you can replace the contained data rather than
7//! modify it.
8//!
9//! ```rust
10//! use arc_atomic_ref::AtomicRef;
11//! use std::sync::Arc;
12//! let ptr = AtomicRef::new(1);
13//! // share ptr with many threads with `clone`
14//! // change its contained value, requires a new `Arc`
15//! ptr.swap(Arc::new(2));
16//! // all threads should see the change, use `.load()` to get the value
17//! assert_eq!(**ptr.load(), 2);
18//! ```
19use std::{ops::Deref, sync::Arc};
20
21use arc_swap::ArcSwap;
22
23/// Stores data in a location accessible to multiple threads but also atomically
24/// swappable
25#[derive(Debug, Default)]
26pub struct AtomicRef<T>(Arc<ArcSwap<T>>);
27
28impl<T> AtomicRef<T> {
29    /// Create new AtomicRef from some `T`
30    pub fn new(store: T) -> Self {
31        Self(Arc::new(ArcSwap::new(Arc::new(store))))
32    }
33}
34
35impl<T> From<Arc<T>> for AtomicRef<T> {
36    fn from(store: Arc<T>) -> Self {
37        Self(Arc::new(ArcSwap::new(store)))
38    }
39}
40
41impl<T> Deref for AtomicRef<T> {
42    type Target = ArcSwap<T>;
43
44    fn deref(&self) -> &Self::Target {
45        &self.0
46    }
47}
48
49impl<T> Clone for AtomicRef<T> {
50    fn clone(&self) -> Self {
51        Self(self.0.clone())
52    }
53}