use std::sync::Arc;
use serde::{de::DeserializeOwned, Serialize};
use crate::wasm::D1WasmStorage;
use crate::core::errors::StorageResult;
pub struct WasmCredentialStore {
storage: Arc<D1WasmStorage>,
}
impl WasmCredentialStore {
#[must_use]
pub fn new(storage: Arc<D1WasmStorage>) -> Self {
Self { storage }
}
pub async fn get<V: DeserializeOwned + Send + 'static>(
&self,
key: &str,
) -> StorageResult<Option<V>> {
self.storage.get_async(key).await
}
pub async fn set<V: Serialize + Send + 'static>(
&self,
key: &str,
value: V,
) -> StorageResult<()> {
self.storage.set_async(key, value).await
}
pub async fn delete(&self, key: &str) -> StorageResult<()> {
self.storage.delete_async(key).await
}
pub async fn exists(&self, key: &str) -> StorageResult<bool> {
self.storage.exists_async(key).await
}
pub async fn list_keys(&self, prefix: Option<&str>) -> StorageResult<Vec<String>> {
self.storage.list_keys_async(prefix).await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::schema::{MIGRATIONS, MigrationRunner};
use foundation_core::valtron::initialize_pool;
fn memory_store() -> WasmCredentialStore {
let storage = Arc::new(D1WasmStorage::memory("test"));
WasmCredentialStore::new(storage)
}
#[test]
fn memory_store_set_and_get() {
let store = memory_store();
pollster::block_on(store.set("test_key", "test_value")).expect("set failed");
let value: Option<String> = pollster::block_on(store.get("test_key"))
.expect("get failed");
assert_eq!(value, Some("test_value".to_string()));
}
#[test]
fn memory_store_get_missing() {
let store = memory_store();
let value: Option<String> = pollster::block_on(store.get("nonexistent"))
.expect("get failed");
assert_eq!(value, None);
}
#[test]
fn memory_store_delete() {
let store = memory_store();
pollster::block_on(store.set("delete_me", "gone")).expect("set failed");
let value: Option<String> = pollster::block_on(store.get("delete_me"))
.expect("get failed");
assert_eq!(value, Some("gone".to_string()));
pollster::block_on(store.delete("delete_me")).expect("delete failed");
let value: Option<String> = pollster::block_on(store.get("delete_me"))
.expect("get failed");
assert_eq!(value, None);
}
#[test]
fn memory_store_exists() {
let store = memory_store();
assert!(!pollster::block_on(store.exists("nope")).expect("exists failed"));
pollster::block_on(store.set("exists", "yes")).expect("set failed");
assert!(pollster::block_on(store.exists("exists")).expect("exists failed"));
}
#[test]
fn memory_store_overwrite() {
let store = memory_store();
pollster::block_on(store.set("key", "v1")).expect("set failed");
pollster::block_on(store.set("key", "v2")).expect("set failed");
let value: Option<String> = pollster::block_on(store.get("key"))
.expect("get failed");
assert_eq!(value, Some("v2".to_string()));
}
#[test]
fn memory_store_list_keys() {
let store = memory_store();
pollster::block_on(store.set("alpha:one", "1")).expect("set failed");
pollster::block_on(store.set("alpha:two", "2")).expect("set failed");
pollster::block_on(store.set("beta:one", "3")).expect("set failed");
let keys = pollster::block_on(store.list_keys(None)).expect("list failed");
assert_eq!(keys.len(), 3);
let keys = pollster::block_on(store.list_keys(Some("alpha:")))
.expect("list failed");
assert_eq!(keys.len(), 2);
assert!(keys.contains(&"alpha:one".to_string()));
assert!(keys.contains(&"alpha:two".to_string()));
}
#[test]
fn memory_store_complex_value() {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct TestData {
name: String,
count: u32,
tags: Vec<String>,
}
let store = memory_store();
let data = TestData {
name: "test".to_string(),
count: 42,
tags: vec!["a".to_string(), "b".to_string()],
};
pollster::block_on(store.set("complex", &data)).expect("set failed");
let retrieved: Option<TestData> = pollster::block_on(store.get("complex"))
.expect("get failed");
assert_eq!(retrieved, Some(data));
}
#[test]
fn memory_store_with_valtron_init() {
initialize_pool(123);
let store = memory_store();
pollster::block_on(store.set("after_init", "works")).expect("set failed");
let value: Option<String> = pollster::block_on(store.get("after_init"))
.expect("get failed");
assert_eq!(value, Some("works".to_string()));
}
#[cfg(feature = "wasm-d1-test")]
mod d1_integration {
use super::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
async fn d1_store_basic() {
}
}
}