use async_trait::async_trait;
use std::collections::{BTreeMap, HashMap};
#[async_trait]
pub trait KeyValueStore<K, V>
where
K: Send + Sync,
V: Send,
{
type Err;
async fn insert(&self, key: K, value: V) -> Result<Option<V>, Self::Err>;
async fn remove(&self, key: &K) -> Result<Option<V>, Self::Err>;
async fn contains(&self, key: &K) -> Result<bool, Self::Err>;
async fn inspect<F>(&self, key: &K, f: F) -> Result<(), Self::Err>
where
F: FnMut(Option<&V>) + Send;
async fn get_clone(&self, key: &K) -> Result<Option<V>, Self::Err>;
async fn get_mut<F>(&self, key: &K, f: F) -> Result<bool, Self::Err>
where
F: FnMut(&mut V) + Send;
async fn get_mut_or_default<F>(&self, key: K, mut f: F) -> Result<(), Self::Err>
where
F: FnMut(&mut V) + Send,
K: 'async_trait,
V: 'async_trait + Default,
{
let v = self.contains(&key).await?;
if v {
self.get_mut(&key, f).await?;
} else {
let mut value = Default::default();
f(&mut value);
self.insert(key, value).await?;
}
Ok(())
}
async fn for_each<F>(&self, f: F) -> Result<(), Self::Err>
where
F: FnMut((&K, &V)) + Send;
async fn for_each_mut<F>(&self, f: F) -> Result<(), Self::Err>
where
F: FnMut((&K, &mut V)) + Send;
}
#[async_trait]
pub trait GetBTreeMap<K, V> {
type Err;
async fn btreemap(&self) -> Result<BTreeMap<K, V>, Self::Err>;
}
#[async_trait]
impl<T, K, V> GetBTreeMap<K, V> for T
where
T: KeyValueStore<K, V, Err = Box<dyn std::error::Error>> + Send + Sync,
V: Clone + Send,
K: Clone + Ord + Send + Sync,
{
type Err = Box<dyn std::error::Error>;
async fn btreemap(&self) -> Result<BTreeMap<K, V>, Self::Err> {
let mut map = BTreeMap::new();
self.for_each(|(k, v)| {
map.insert(k.clone(), v.clone());
})
.await?;
Ok(map)
}
}
#[async_trait]
pub trait GetHashMap<K, V> {
type Err;
async fn hashmap(&self) -> Result<HashMap<K, V>, Self::Err>;
}
#[async_trait]
impl<T, K, V> GetHashMap<K, V> for T
where
T: KeyValueStore<K, V, Err = Box<dyn std::error::Error>> + Send + Sync,
V: Clone + Send,
K: Clone + std::hash::Hash + Eq + Send + Sync,
{
type Err = Box<dyn std::error::Error>;
async fn hashmap(&self) -> Result<HashMap<K, V>, Self::Err> {
let mut map: HashMap<K, V> = Default::default();
self.for_each(|(k, v)| {
map.insert(k.clone(), v.clone());
})
.await?;
Ok(map)
}
}