taplo/util/
shared.rs

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}