use std::marker::PhantomData;
use std::sync::Arc;
use std::time::Duration;
use serde::Serialize;
use serde::de::DeserializeOwned;
use rskit_errors::{AppError, AppResult, ErrorCode};
use crate::registry::CacheStore;
pub struct TypedStore<T> {
client: Arc<dyn CacheStore>,
prefix: String,
_marker: PhantomData<T>,
}
impl<T: Serialize + DeserializeOwned + Send + Sync> TypedStore<T> {
pub fn new(client: Arc<dyn CacheStore>, prefix: impl Into<String>) -> Self {
Self {
client,
prefix: prefix.into(),
_marker: PhantomData,
}
}
fn full_key(&self, key: &str) -> String {
format!("{}:{}", self.prefix, key)
}
pub async fn get(&self, key: &str) -> AppResult<Option<T>> {
let raw = self.client.get(&self.full_key(key)).await?;
match raw {
Some(json) => {
let val = serde_json::from_str(&json).map_err(|e| {
AppError::new(ErrorCode::Internal, format!("json deserialise error: {e}"))
.with_cause(e)
})?;
Ok(Some(val))
}
None => Ok(None),
}
}
pub async fn set(&self, key: &str, val: &T, ttl: Option<Duration>) -> AppResult<()> {
let json = serde_json::to_string(val).map_err(|e| {
AppError::new(ErrorCode::Internal, format!("json serialise error: {e}")).with_cause(e)
})?;
self.client.set(&self.full_key(key), &json, ttl).await
}
pub async fn delete(&self, key: &str) -> AppResult<bool> {
self.client.delete(&self.full_key(key)).await
}
pub async fn exists(&self, key: &str) -> AppResult<bool> {
self.client.exists(&self.full_key(key)).await
}
}