statewatcher/
state_reader.rs1use std::sync::{
2 Arc, RwLock, RwLockReadGuard,
3 atomic::{AtomicBool, Ordering},
4};
5
6#[derive(Clone)]
7pub struct StateReader<T> {
8 pub(crate) inner: Arc<(RwLock<T>, AtomicBool)>,
9}
10
11impl<T> StateReader<T>
12where
13 T: Clone,
14{
15 #[inline]
16 fn lock<'a>(&'a self) -> RwLockReadGuard<'a, T> {
17 match self.inner.0.read() {
18 Ok(g) => g,
19 Err(p) => p.into_inner(),
20 }
21 }
22
23 pub fn latest(&self) -> Option<T> {
24 if self.inner.1.load(Ordering::Acquire) {
25 let guard = self.lock();
26 Some(guard.clone())
27 } else {
28 None
29 }
30 }
31
32 pub fn latest_and_clear(&self) -> Option<T> {
33 if self.inner.1.swap(false, Ordering::AcqRel) {
34 let guard = self.lock();
35 Some(guard.clone())
36 } else {
37 None
38 }
39 }
40
41 pub fn with_state<F, R>(&self, f: F) -> R
42 where
43 F: FnOnce(&T) -> R,
44 {
45 let guard = self.lock();
46 f(&*guard)
47 }
48}