use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::sync::Arc;
struct Inner<T> {
value: RwLock<T>,
}
#[derive(Clone)]
pub struct Writer<T>(Arc<Inner<T>>);
impl<T> std::fmt::Debug for Writer<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Writer").finish()
}
}
impl<T> Writer<T> {
pub fn new(value: T) -> Self {
Self(Arc::new(Inner {
value: RwLock::new(value),
}))
}
pub fn write(&self) -> RwLockWriteGuard<'_, T> {
self.0.value.write()
}
pub fn read(&self) -> RwLockReadGuard<'_, T> {
self.0.value.read()
}
pub fn reader(&self) -> Reader<T> {
Reader(self.0.clone())
}
}
#[derive(Clone)]
pub struct Reader<T>(Arc<Inner<T>>);
impl<T> Reader<T> {
pub fn project<U>(&self, f: impl Fn(&T) -> U) -> U {
let value = self.0.value.read();
f(&*value)
}
}
impl<T: Copy> Reader<T> {
pub fn get(&self) -> T {
*self.0.value.read()
}
}
impl<T: Clone> Reader<T> {
pub fn get_cloned(&self) -> T {
self.0.value.read().clone()
}
}