mod dirty;
use dirty::Dirty;
cfg_if::cfg_if! {
if #[cfg(with_indexed_db)] {
pub mod indexed_db;
pub use indexed_db::IndexedDb;
}
}
cfg_if::cfg_if! {
if #[cfg(feature = "fs")] {
pub mod file;
pub use file::File;
}
}
pub mod memory;
use std::ops::Deref;
pub use memory::Memory;
#[trait_variant::make(Persist: Send)]
pub trait LocalPersist: Deref {
type Error: std::error::Error + Send + Sync + 'static;
fn as_mut(&mut self) -> &mut Self::Target;
async fn persist(&mut self) -> Result<(), Self::Error>;
fn into_value(self) -> Self::Target
where
Self::Target: Sized;
}
#[allow(async_fn_in_trait)]
pub trait LocalPersistExt: LocalPersist {
async fn mutate<R>(
&mut self,
mutation: impl FnOnce(&mut Self::Target) -> R,
) -> Result<R, Self::Error>;
}
#[trait_variant::make(Send)]
pub trait PersistExt: Persist {
async fn mutate<R: Send>(
&mut self,
mutation: impl FnOnce(&mut Self::Target) -> R + Send,
) -> Result<R, Self::Error>;
}
#[allow(async_fn_in_trait)]
impl<T: LocalPersist> LocalPersistExt for T {
async fn mutate<R>(
&mut self,
mutation: impl FnOnce(&mut Self::Target) -> R,
) -> Result<R, Self::Error> {
let output = mutation(self.as_mut());
self.persist().await?;
Ok(output)
}
}
impl<T: Persist> PersistExt for T {
async fn mutate<R>(
&mut self,
mutation: impl FnOnce(&mut Self::Target) -> R + Send,
) -> Result<R, Self::Error> {
let output = mutation(self.as_mut());
self.persist().await?;
Ok(output)
}
}