1use std::{hash::Hash, sync::Arc};
2
3use arc_swap::{ArcSwapOption, Guard};
4
5#[derive(Debug)]
6pub struct Shared<T>(ArcSwapOption<T>)
7where
8 T: Clone;
9
10impl<T> Hash for Shared<T>
11where
12 T: Clone + Hash,
13{
14 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
15 self.0.load().hash(state)
16 }
17}
18
19impl<T> PartialEq for Shared<T>
20where
21 T: Clone + PartialEq,
22{
23 fn eq(&self, other: &Self) -> bool {
24 *self.0.load() == *other.0.load()
25 }
26}
27
28impl<T> Eq for Shared<T> where T: Clone + Eq {}
29
30impl<T> Default for Shared<T>
31where
32 T: Clone + Default,
33{
34 fn default() -> Self {
35 Self(ArcSwapOption::new(Some(Arc::new(T::default()))))
36 }
37}
38
39impl<T> Shared<T>
40where
41 T: Clone,
42{
43 pub fn get(&self) -> Arc<T> {
44 self.0.load_full().unwrap()
45 }
46
47 pub fn read(&self) -> SharedGuard<T> {
48 SharedGuard(self.0.load())
49 }
50
51 pub(crate) fn new(value: T) -> Self {
52 value.into()
53 }
54
55 pub(crate) fn update(&self, f: impl FnOnce(&mut T)) {
56 let mut inner = self.0.load_full().unwrap();
57 f(Arc::make_mut(&mut inner));
58 self.0.store(Some(inner))
59 }
60}
61
62impl<T: Clone> From<T> for Shared<T> {
63 fn from(value: T) -> Self {
64 Self(ArcSwapOption::new(Some(Arc::new(value))))
65 }
66}
67
68pub struct SharedGuard<T: Clone>(Guard<Option<Arc<T>>>);
69
70impl<T: Clone> std::ops::Deref for SharedGuard<T> {
71 type Target = Arc<T>;
72
73 fn deref(&self) -> &Self::Target {
74 self.0.as_ref().unwrap()
75 }
76}