use serde::Serialize;
use serde_json::Value;
use std::{path::Path, sync::Arc};
use crate::adapter::KyvalStoreBuilder;
use crate::{Store, StoreError, StoreModel};
#[derive(thiserror::Error, Debug)]
pub enum KyvalError {
#[error("Store error: {0}")]
StoreError(#[from] StoreError),
}
pub struct Kyval {
store: Arc<dyn Store>,
}
impl Kyval {
pub async fn try_new<S: Store + 'static>(
store: S,
) -> Result<Self, KyvalError> {
store.initialize().await?;
Ok(Self {
store: Arc::new(store),
})
}
pub async fn set<T: Serialize>(
&self,
key: &str,
value: T,
) -> Result<Option<StoreModel>, KyvalError> {
let json_value = serde_json::to_value(value)
.map_err(|e| StoreError::SerializationError { source: e })?;
Ok(self.store.set(key, json_value, None).await?)
}
pub async fn set_with_ttl<T: Serialize>(
&self,
key: &str,
value: T,
ttl: u64,
) -> Result<Option<StoreModel>, KyvalError> {
let json_value = serde_json::to_value(value)
.map_err(|e| StoreError::SerializationError { source: e })?;
Ok(self.store.set(key, json_value, Some(ttl)).await?)
}
pub async fn get(&self, key: &str) -> Result<Option<Value>, KyvalError> {
Ok(self.store.get(key).await?)
}
pub async fn list(&self) -> Result<Vec<StoreModel>, KyvalError> {
Ok(self.store.list().await?)
}
pub async fn remove(&self, key: &str) -> Result<(), KyvalError> {
Ok(self.store.remove(key).await?)
}
pub async fn remove_many<T: AsRef<str> + Sync>(
&self,
keys: &[T],
) -> Result<(), KyvalError> {
let keys: Vec<&str> = keys.iter().map(|k| k.as_ref()).collect();
Ok(self.store.remove_many(&keys).await?)
}
pub async fn clear(&self) -> Result<(), KyvalError> {
Ok(self.store.clear().await?)
}
}
impl Default for Kyval {
fn default() -> Self {
let runtime = tokio::runtime::Runtime::new()
.expect("Failed to create async runtime");
let store = runtime.block_on(async {
KyvalStoreBuilder::new()
.uri(Path::new(":memory:"))
.build()
.await
.expect("Failed to build KyvalStore")
});
Self {
store: Arc::new(store),
}
}
}