use std::cell::Cell;
pub trait BackendSyncable {
type Backend;
type Error;
fn sync_to_backend(&self, backend: &Self::Backend) -> Result<(), Self::Error>;
}
pub struct SyncManager<T: BackendSyncable> {
data: T,
backend: T::Backend,
dirty: Cell<bool>,
}
impl<T: BackendSyncable> SyncManager<T> {
pub fn new(data: T, backend: T::Backend) -> Self {
Self {
data,
backend,
dirty: Cell::new(true),
}
}
pub fn data_mut(&mut self) -> &mut T {
self.dirty.set(true);
&mut self.data
}
pub fn data(&self) -> &T {
&self.data
}
pub fn backend(&self) -> Result<&T::Backend, T::Error> {
self.ensure_synced()?;
Ok(&self.backend)
}
fn ensure_synced(&self) -> Result<(), T::Error> {
if self.dirty.get() {
self.data.sync_to_backend(&self.backend)?;
self.dirty.set(false);
}
Ok(())
}
}