use std::marker::PhantomData;
use std::path::Path;
use crate::token::{Hash, Token};
use crate::txn::Txn;
pub struct Store<T: Hash>(kv::Store, PhantomData<T>);
impl<T: Hash> From<kv::Store> for Store<T> {
fn from(store: kv::Store) -> Store<T> {
Store(store, PhantomData)
}
}
impl<T: Hash> From<Store<T>> for kv::Store {
fn from(store: Store<T>) -> kv::Store {
store.0
}
}
pub struct Config<T: Hash>(kv::Config, PhantomData<T>);
impl<T: Hash> From<kv::Config> for Config<T> {
fn from(cfg: kv::Config) -> Config<T> {
Config(cfg, PhantomData)
}
}
impl<T: Hash> From<Config<T>> for kv::Config {
fn from(cfg: Config<T>) -> kv::Config {
cfg.0
}
}
impl<T: Hash> AsRef<kv::Store> for Store<T> {
fn as_ref(&self) -> &kv::Store {
&self.0
}
}
impl<T: Hash> AsMut<kv::Store> for Store<T> {
fn as_mut(&mut self) -> &mut kv::Store {
&mut self.0
}
}
impl<T: Hash> Store<T> {
pub fn config<P: AsRef<Path>>(path: P) -> Config<T> {
kv::Config::default(path).into()
}
pub fn new<C: Into<kv::Config>>(cfg: C) -> Result<Store<T>, kv::Error> {
Ok(Store(kv::Store::new(cfg.into())?, PhantomData))
}
pub fn read_txn<'a>(&'a self) -> Result<Txn<'a, T>, kv::Error> {
Ok(Txn::from(self.0.read_txn()?))
}
pub fn with_read_txn<'a, Res, F: FnOnce(&Txn<'a, T>) -> Result<Res, kv::Error>>(
&'a self,
f: F,
) -> Result<Res, kv::Error> {
let txn = self.read_txn()?;
f(&txn)
}
pub fn write_txn<'a>(&'a mut self) -> Result<Txn<'a, T>, kv::Error> {
Ok(Txn::from(self.0.write_txn()?))
}
pub fn with_write_txn<'a, Res, F: FnOnce(&mut Txn<'a, T>) -> Result<Res, kv::Error>>(
&'a mut self,
f: F,
) -> Result<Res, kv::Error> {
let mut txn = self.write_txn()?;
let res = f(&mut txn)?;
txn.0.commit()?;
Ok(res)
}
pub fn bucket<'a, V: kv::Value<'a>>(
&self,
name: Option<&str>,
) -> Result<kv::Bucket<'a, Token<T>, V>, kv::Error> {
self.0.bucket(name)
}
}