use crate::Args;
use serde::{de::DeserializeOwned, Serialize};
#[cfg(feature = "sled")]
use super::sled::Db;
#[cfg(not(feature = "sled"))]
use super::file::Db;
pub struct Cache {
db: Option<Db>,
}
impl Cache {
pub fn open(args: &Args, group: impl AsRef<str>) -> Self {
let group = group.as_ref();
let db = if args.no_cache {
None
} else {
let path = args.cache_dir.as_ref().unwrap().join(group);
Self::_open(&path)
};
Self { db }
}
pub fn get<K, V>(&self, key: &K) -> Option<V>
where
K: Serialize,
V: DeserializeOwned,
{
let key = _serialize_key(key)?;
let db = self.db.as_ref()?;
let val = Self::_get(db, &key)?;
json::from_slice(val.as_ref())
.map_err(|error| {
log::error!("Unable to parse cached value due to: {}", error);
})
.ok()
}
fn put_<K, V>(&self, key: &K, val: &V) -> Option<()>
where
K: Serialize,
V: Serialize,
{
let key = _serialize_key(key)?;
let val = _serialize_val(val)?;
let db = self.db.as_ref()?;
Self::_put(db, &key, &val)
}
pub fn put<K, V>(&self, key: &K, val: &V)
where
K: Serialize,
V: Serialize,
{
let _ = self.put_(key, val);
}
fn del_<K>(&self, key: &K) -> Option<()>
where
K: Serialize,
{
let key = _serialize_key(key)?;
let db = self.db.as_ref()?;
Self::_del(db, &key)
}
pub fn del<K>(&self, key: &K)
where
K: Serialize,
{
let _ = self.del_(key);
}
}
fn _serialize_key<K>(key: &K) -> Option<Vec<u8>>
where
K: Serialize,
{
json::to_vec(key)
.map_err(|error| log::error!("Unable to serialize cache key due to: {}", error))
.ok()
.map(_sha256)
}
fn _serialize_val<V>(val: &V) -> Option<Vec<u8>>
where
V: Serialize,
{
json::to_vec(val)
.map_err(|error| log::error!("Unable to serialize cache value due to: {}", error))
.ok()
}
fn _sha256(data: impl AsRef<[u8]>) -> Vec<u8> {
#[cfg(feature = "crypto-hashes")]
use crypto_hashes::{digest::Digest, sha3::Sha3_256 as Hasher};
#[cfg(feature = "hmac-sha256")]
use hmac_sha256::Hash as Hasher;
let mut hasher = Hasher::default();
hasher.update(data.as_ref());
let hash = hasher.finalize();
Vec::from(&hash as &[u8])
}