use std::{
cell::{Ref, RefCell, RefMut},
fmt::Debug,
};
use crate::{guarantee::PathExtGuaranteed, path::Path, trackable::Trackable, wakers::StoreWakers};
pub struct Store<S> {
data: RefCell<S>,
wakers: RefCell<StoreWakers>,
}
impl<S> Store<S> {
pub fn new(data: S) -> Self {
Self {
data: RefCell::new(data),
wakers: RefCell::new(StoreWakers::new()),
}
}
}
impl<S: Trackable> Store<S> {
pub fn build_path(&self) -> StoreRoot<'_, S> {
S::new_path_builder(RootPath { store: self })
}
}
pub type StoreRoot<'s, S> = <S as Trackable>::PathBuilder<RootPath<'s, S>>;
pub struct RootPath<'s, S> {
store: &'s Store<S>,
}
impl<'s, S> Clone for RootPath<'s, S> {
fn clone(&self) -> Self {
Self { store: self.store }
}
}
impl<'s, S> Copy for RootPath<'s, S> {}
impl<'s, S> Debug for RootPath<'s, S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("Root")
}
}
impl<'s, S> Path for RootPath<'s, S> {
type Out = S;
fn path_borrow(&self) -> Option<Ref<'_, Self::Out>> {
Some(self.store.data.borrow())
}
fn path_borrow_mut(&self) -> Option<RefMut<'_, Self::Out>> {
Some(self.store.data.borrow_mut())
}
fn visit_hashes(&self, visitor: &mut crate::hash_visitor::HashVisitor) {
visitor.finish_one();
}
fn store_wakers(&self) -> &RefCell<StoreWakers> {
&self.store.wakers
}
}
impl<'s, S> PathExtGuaranteed for RootPath<'s, S> {}