use crate::{
crypto::{asym::KeyPair, DetachedKey, EncryptedMap},
notify::{Lock, LockNotify, Notify},
Id,
};
use async_std::{sync::Arc, task};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{
cmp::{Ord, Ordering as Order , PartialOrd},
hash::Hash,
path::PathBuf,
};
#[derive(Serialize, Deserialize, Eq, PartialEq, Hash)]
pub(crate) struct CombKey {
pub(crate) id: Id,
pub(crate) zone: String,
}
impl Ord for CombKey {
fn cmp(&self, other: &Self) -> Order {
self.id.cmp(&other.id).then(self.zone.cmp(&other.zone))
}
}
impl PartialOrd for CombKey {
fn partial_cmp(&self, other: &Self) -> Option<Order> {
self.id.partial_cmp(&other.id).and_then(|id| {
self.zone
.partial_cmp(&other.zone)
.and_then(|zone| Some(id.then(zone)))
})
}
}
impl ToString for CombKey {
fn to_string(&self) -> String {
format!("{}/{}", self.id, self.zone)
}
}
pub(crate) type CacheRef<K, V> = Arc<Cache<K, V>>;
pub(crate) struct Cache<K, V>
where
K: Serialize + DeserializeOwned + Ord + PartialOrd + Hash + ToString,
V: DetachedKey<KeyPair> + Serialize + DeserializeOwned,
{
cache: LockNotify<EncryptedMap<K, Notify<V>, KeyPair>>,
path: Option<PathBuf>,
}
impl<K, V> Cache<K, V>
where
K: Serialize + DeserializeOwned + Ord + PartialOrd + Hash + ToString,
V: DetachedKey<KeyPair> + Serialize + DeserializeOwned,
{
pub(crate) fn new<P>(path: P) -> CacheRef<K, V>
where
P: Into<Option<PathBuf>>,
{
Arc::new(Self {
cache: Notify::new(Lock::new(EncryptedMap::new())),
path: path.into(),
})
}
pub(crate) fn hot(self: Arc<Self>) {
let path = self.path.as_ref().expect("Can't set cache without path to 'hot'");
task::spawn(async move {});
}
}