celerix_store/
lib.rs

1//! Celerix Store is a lightweight, low-latency Key-Value (KV) data store.
2//! 
3//! It is designed with a "Liquid Data" architecture using a `Persona -> App -> Key` hierarchy.
4//! This Rust implementation provides 1:1 parity with the original Go version, including
5//! atomic persistence and AES-256-GCM client-side encryption.
6//!
7//! ## Core Components
8//! - [`engine`]: The storage backend (In-memory with persistence).
9//! - [`sdk`]: Client libraries for both embedded and remote (TCP) modes.
10//! - [`server`]: TCP daemon implementation.
11
12pub mod engine;
13pub mod sdk;
14pub mod server;
15
16use serde_json;
17use thiserror::Error;
18use async_trait::async_trait;
19use std::collections::HashMap;
20
21/// Errors returned by the Celerix Store.
22#[derive(Error, Debug)]
23pub enum Error {
24    /// The requested persona does not exist.
25    #[error("persona not found")]
26    PersonaNotFound,
27    /// The requested app does not exist within the persona.
28    #[error("app not found")]
29    AppNotFound,
30    /// The requested key does not exist within the app.
31    #[error("key not found")]
32    KeyNotFound,
33    /// An internal error occurred.
34    #[error("internal error: {0}")]
35    Internal(String),
36    /// An I/O error occurred during persistence or network communication.
37    #[error("IO error: {0}")]
38    Io(#[from] std::io::Error),
39    /// Error during JSON serialization or deserialization.
40    #[error("Serialization error: {0}")]
41    Serialization(#[from] serde_json::Error),
42}
43
44/// A specialized Result type for Celerix Store operations.
45pub type Result<T> = std::result::Result<T, Error>;
46
47/// Reserved ID for global/system-level data.
48pub const SYSTEM_PERSONA: &str = "_system";
49
50/// Defines basic read operations for the store.
51#[async_trait]
52pub trait KVReader: Send + Sync {
53    /// Retrieves a value for a specific persona, app, and key.
54    async fn get(&self, persona_id: &str, app_id: &str, key: &str) -> Result<serde_json::Value>;
55}
56
57/// Defines basic write and delete operations for the store.
58#[async_trait]
59pub trait KVWriter: Send + Sync {
60    /// Stores a value for a specific persona, app, and key.
61    async fn set(&self, persona_id: &str, app_id: &str, key: &str, value: serde_json::Value) -> Result<()>;
62    /// Deletes a key from a specific persona and app.
63    async fn delete(&self, persona_id: &str, app_id: &str, key: &str) -> Result<()>;
64}
65
66/// Allows discovering personas and apps within the store.
67#[async_trait]
68pub trait AppEnumeration: Send + Sync {
69    /// Lists all available persona IDs.
70    async fn get_personas(&self) -> Result<Vec<String>>;
71    /// Lists all app IDs for a given persona.
72    async fn get_apps(&self, persona_id: &str) -> Result<Vec<String>>;
73}
74
75/// Allows retrieving bulk data from the store.
76#[async_trait]
77pub trait BatchExporter: Send + Sync {
78    /// Returns all key-value pairs for a specific app within a persona.
79    async fn get_app_store(&self, persona_id: &str, app_id: &str) -> Result<HashMap<String, serde_json::Value>>;
80    /// Returns data for a specific app across all personas.
81    async fn dump_app(&self, app_id: &str) -> Result<HashMap<String, HashMap<String, serde_json::Value>>>;
82}
83
84/// Allows searching for keys across all personas.
85#[async_trait]
86pub trait GlobalSearcher: Send + Sync {
87    /// Finds a key within an app by searching all personas. Returns the value and the persona ID where it was found.
88    async fn get_global(&self, app_id: &str, key: &str) -> Result<(serde_json::Value, String)>;
89}
90
91/// Handles higher-level data operations like moving keys between personas.
92#[async_trait]
93pub trait Orchestrator: Send + Sync {
94    /// Moves a key from one persona to another within the same app.
95    async fn move_key(&self, src_persona: &str, dst_persona: &str, app_id: &str, key: &str) -> Result<()>;
96}
97
98/// The primary interface for interacting with the Celerix Store.
99/// 
100/// It combines all functional traits for a complete storage experience.
101#[async_trait]
102pub trait CelerixStore: KVReader + KVWriter + AppEnumeration + BatchExporter + GlobalSearcher + Orchestrator {
103    /// Returns an [`AppScope`] that simplifies operations by pinning a persona and app.
104    fn app(&self, persona_id: &str, app_id: &str) -> Box<dyn AppScope + '_>;
105}
106
107/// A simplified, scoped interface for a specific persona and app.
108#[async_trait]
109pub trait AppScope: Send + Sync {
110    /// Retrieves a value from the scoped app.
111    async fn get(&self, key: &str) -> Result<serde_json::Value>;
112    /// Stores a value in the scoped app.
113    async fn set(&self, key: &str, value: serde_json::Value) -> Result<()>;
114    /// Deletes a key from the scoped app.
115    async fn delete(&self, key: &str) -> Result<()>;
116    /// Returns a [`VaultScope`] for client-side encrypted storage using the provided master key.
117    fn vault(&self, master_key: &[u8]) -> Box<dyn VaultScope + '_>;
118}
119
120/// A scoped interface for performing client-side encryption.
121#[async_trait]
122pub trait VaultScope: Send + Sync {
123    /// Retrieves and decrypts a value from the scoped app.
124    async fn get(&self, key: &str) -> Result<String>;
125    /// Encrypts and stores a plaintext string in the scoped app.
126    async fn set(&self, key: &str, plaintext: &str) -> Result<()>;
127}