1pub use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
25
26pub use self::{
27 ro::RoData,
28 rw::{ReadWriteGuard, RwData},
29};
30
31pub mod context;
32mod ro;
33mod rw;
34
35pub trait Data<T>: private::InnerData<T>
37where
38 T: ?Sized,
39{
40 fn to_ro(&self) -> RoData<T>;
41
42 fn has_changed(&self) -> bool;
43}
44
45pub struct DataMap<I: ?Sized + Send + Sync + 'static, O> {
46 data: RoData<I>,
47 f: Box<dyn FnMut() -> O + Send + Sync>,
48}
49
50impl<I: ?Sized + Send + Sync + 'static, O> DataMap<I, O> {
51 pub fn fns(
52 self,
53 ) -> (
54 Box<dyn FnMut() -> O + Send + Sync>,
55 Box<dyn Fn() -> bool + Send + Sync>,
56 ) {
57 let checker = Box::new(move || self.data.has_changed());
58 (self.f, checker)
59 }
60}
61
62impl<I: ?Sized + Send + Sync + 'static, O: 'static> DataMap<I, O> {
63 pub fn map<O2>(mut self, mut f: impl FnMut(O) -> O2 + Send + Sync + 'static) -> DataMap<I, O2> {
64 DataMap {
65 data: self.data,
66 f: Box::new(move || f((self.f)())),
67 }
68 }
69}
70
71impl<I: ?Sized + Send + Sync + 'static> RwData<I> {
72 pub fn map<O>(&self, mut f: impl FnMut(&I) -> O + Send + Sync + 'static) -> DataMap<I, O> {
73 let data = RoData::from(self);
74 let f = move || f(&*data.read());
75 DataMap { data: RoData::from(self), f: Box::new(f) }
76 }
77}
78
79impl<I: ?Sized + Send + Sync + 'static> RoData<I> {
80 pub fn map<O>(&self, mut f: impl FnMut(&I) -> O + Send + Sync + 'static) -> DataMap<I, O> {
81 let data = self.clone();
82 let f = move || f(&*data.read());
83 DataMap { data: self.clone(), f: Box::new(f) }
84 }
85}
86
87mod private {
88 use std::sync::{Arc, atomic::AtomicUsize};
89
90 use super::RwLockReadGuard;
91
92 pub trait InnerData<T: ?Sized> {
93 fn data(&self) -> RwLockReadGuard<'_, T>;
95
96 fn try_data(&self) -> Option<RwLockReadGuard<'_, T>>;
98
99 fn cur_state(&self) -> &Arc<AtomicUsize>;
101
102 fn read_state(&self) -> &AtomicUsize;
104 }
105}