commit bc072421f5bf0c99586deca88d018dca01e9f33a
parent 35f6cdfc8168d690f1ad0790a11fe48565e3d702
Author: triesap <triesap@radroots.dev>
Date: Mon, 19 Jan 2026 00:48:55 +0000
app-core: add datastore types and trait
- define datastore entry/value types and result alias
- add async datastore trait with core operations
- wire backup payload integration for datastore exports
- add unit test for datastore entry helper
Diffstat:
5 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -1150,6 +1150,7 @@ name = "radroots-app-core"
version = "0.1.0"
dependencies = [
"async-trait",
+ "serde",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
@@ -15,6 +15,7 @@ license = "AGPL-3.0"
[workspace.dependencies]
leptos = { version = "0.8.5", default-features = false }
wasm-bindgen = "=0.2.100"
+serde = { version = "1", features = ["derive"] }
[profile.release]
codegen-units = 1
diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml
@@ -11,3 +11,4 @@ crate-type = ["rlib"]
[dependencies]
async-trait = "0.1.83"
+serde = { workspace = true }
diff --git a/crates/core/src/datastore/mod.rs b/crates/core/src/datastore/mod.rs
@@ -1,3 +1,11 @@
pub mod error;
+pub mod types;
pub use error::{RadrootsClientDatastoreError, RadrootsClientDatastoreErrorMessage};
+pub use types::{
+ RadrootsClientDatastore,
+ RadrootsClientDatastoreEntries,
+ RadrootsClientDatastoreEntry,
+ RadrootsClientDatastoreResult,
+ RadrootsClientDatastoreValue,
+};
diff --git a/crates/core/src/datastore/types.rs b/crates/core/src/datastore/types.rs
@@ -0,0 +1,83 @@
+use async_trait::async_trait;
+use serde::de::DeserializeOwned;
+use serde::Serialize;
+
+use crate::backup::RadrootsClientBackupDatastorePayload;
+use crate::idb::RadrootsClientIdbConfig;
+
+use super::RadrootsClientDatastoreError;
+
+pub type RadrootsClientDatastoreValue = Option<String>;
+pub type RadrootsClientDatastoreResult<T> = Result<T, RadrootsClientDatastoreError>;
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct RadrootsClientDatastoreEntry {
+ pub key: String,
+ pub value: RadrootsClientDatastoreValue,
+}
+
+impl RadrootsClientDatastoreEntry {
+ pub fn new(key: impl Into<String>, value: RadrootsClientDatastoreValue) -> Self {
+ Self {
+ key: key.into(),
+ value,
+ }
+ }
+}
+
+pub type RadrootsClientDatastoreEntries = Vec<RadrootsClientDatastoreEntry>;
+
+#[async_trait(?Send)]
+pub trait RadrootsClientDatastore {
+ fn get_config(&self) -> RadrootsClientIdbConfig;
+ fn get_store_id(&self) -> &str;
+
+ async fn init(&self) -> RadrootsClientDatastoreResult<()>;
+ async fn set(&self, key: &str, value: &str) -> RadrootsClientDatastoreResult<String>;
+ async fn get(&self, key: &str) -> RadrootsClientDatastoreResult<String>;
+ async fn set_obj<T>(&self, key: &str, value: &T) -> RadrootsClientDatastoreResult<T>
+ where
+ T: Serialize + DeserializeOwned + Clone;
+ async fn update_obj<T>(&self, key: &str, value: &T) -> RadrootsClientDatastoreResult<T>
+ where
+ T: Serialize + DeserializeOwned + Clone;
+ async fn get_obj<T>(&self, key: &str) -> RadrootsClientDatastoreResult<T>
+ where
+ T: DeserializeOwned;
+ async fn del_obj(&self, key: &str) -> RadrootsClientDatastoreResult<String>;
+ async fn del(&self, key: &str) -> RadrootsClientDatastoreResult<String>;
+ async fn del_pref(&self, key_prefix: &str) -> RadrootsClientDatastoreResult<Vec<String>>;
+ async fn set_param(
+ &self,
+ key: &str,
+ key_param: &str,
+ value: &str,
+ ) -> RadrootsClientDatastoreResult<String>;
+ async fn get_param(
+ &self,
+ key: &str,
+ key_param: &str,
+ ) -> RadrootsClientDatastoreResult<String>;
+ async fn keys(&self) -> RadrootsClientDatastoreResult<Vec<String>>;
+ async fn entries(&self) -> RadrootsClientDatastoreResult<RadrootsClientDatastoreEntries>;
+ async fn reset(&self) -> RadrootsClientDatastoreResult<()>;
+ async fn export_backup(
+ &self,
+ ) -> RadrootsClientDatastoreResult<RadrootsClientBackupDatastorePayload>;
+ async fn import_backup(
+ &self,
+ payload: RadrootsClientBackupDatastorePayload,
+ ) -> RadrootsClientDatastoreResult<()>;
+}
+
+#[cfg(test)]
+mod tests {
+ use super::RadrootsClientDatastoreEntry;
+
+ #[test]
+ fn entry_builder_preserves_values() {
+ let entry = RadrootsClientDatastoreEntry::new("key", Some(String::from("value")));
+ assert_eq!(entry.key, "key");
+ assert_eq!(entry.value.as_deref(), Some("value"));
+ }
+}