use crate::tree::HashOutput;
mod r#async;
mod memory;
pub use crate::store::r#async::{AsyncStore, AsyncStoreRead, AsyncStoreWrite};
pub use crate::store::memory::MemoryStore;
pub trait Hashable {
fn hash(&self) -> HashOutput;
}
pub trait StoreBase {
type Key;
type Value;
}
pub trait StoreRead: StoreBase {
fn get(&self, key: &Self::Key) -> Option<Self::Value>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub trait StoreWrite: StoreBase {
fn insert(&self, key: Self::Key, value: Self::Value);
fn delete(&self, key: &Self::Key) -> bool;
}
pub trait Store: StoreRead + StoreWrite {}
impl<T> Store for T where T: StoreRead + StoreWrite {}
pub trait OrderedStoreRead: StoreRead<Key: Ord> {
fn last(&self) -> Option<(Self::Key, Self::Value)>;
}
pub trait OrderedStore: OrderedStoreRead + StoreWrite {}
impl<T> OrderedStore for T where T: OrderedStoreRead + StoreWrite {}
pub trait AppendableStore: OrderedStoreRead {
fn append(&self, value: Self::Value) -> Self::Key;
}
pub trait SearchableStoreRead: OrderedStoreRead {
fn filter(
&self,
pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
) -> Vec<(Self::Key, Self::Value)>;
fn find(
&self,
mut pred: impl FnMut(&Self::Key, &Self::Value) -> bool,
) -> Option<(Self::Key, Self::Value)> {
let mut found = false;
let vals = self.filter(|key, value| {
if !found && pred(key, value) {
found = true;
true
} else {
false
}
});
if found {
assert_eq!(vals.len(), 1);
Some(vals.into_iter().next().unwrap())
} else {
None
}
}
}
pub trait SearchableStore: SearchableStoreRead + StoreWrite {}
impl<T> SearchableStore for T where T: SearchableStoreRead + StoreWrite {}