app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

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:
MCargo.lock | 1+
MCargo.toml | 1+
Mcrates/core/Cargo.toml | 1+
Mcrates/core/src/datastore/mod.rs | 8++++++++
Acrates/core/src/datastore/types.rs | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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")); + } +}