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 StoreRead<K, V> {
fn get(&self, key: &K) -> Option<V>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub trait StoreWrite<K, V> {
fn insert(&self, key: K, value: V);
fn delete(&self, key: &K) -> bool;
}
pub trait Store<K, V>: StoreRead<K, V> + StoreWrite<K, V> {}
impl<K, V, T> Store<K, V> for T where T: StoreRead<K, V> + StoreWrite<K, V> {}
pub trait OrderedStoreRead<K: Ord, V>: StoreRead<K, V> {
fn last(&self) -> Option<(K, V)>;
}
pub trait OrderedStore<K: Ord, V>: OrderedStoreRead<K, V> + StoreWrite<K, V> {}
impl<K, V, T> OrderedStore<K, V> for T
where
K: Ord,
T: OrderedStoreRead<K, V> + StoreWrite<K, V>,
{
}
pub trait AppendableStore<K: Ord, V>: OrderedStoreRead<K, V> {
fn append(&self, value: V) -> K;
}
pub trait SearchableStoreRead<K: Ord, V>: OrderedStoreRead<K, V> {
fn filter(&self, pred: impl FnMut(&K, &V) -> bool) -> Vec<(K, V)>;
fn find(&self, mut pred: impl FnMut(&K, &V) -> bool) -> Option<(K, V)> {
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<K: Ord, V>: SearchableStoreRead<K, V> + StoreWrite<K, V> {}
impl<K, V, T> SearchableStore<K, V> for T
where
K: Ord,
T: SearchableStoreRead<K, V> + StoreWrite<K, V>,
{
}