Skip to main content

wacore/store/
cache.rs

1//! Pluggable cache storage trait.
2//!
3//! Implementations of [`CacheStore`] can back any of the client's data caches
4//! (group metadata, device lists, LID-PN mappings, etc.). The default behaviour
5//! uses in-process moka caches; a Redis, Memcached, or any other implementation
6//! can be plugged in via [`CacheConfig`](crate::CacheConfig).
7
8use async_trait::async_trait;
9use std::time::Duration;
10
11/// Backend trait for pluggable cache storage.
12///
13/// Keys and values are opaque strings / bytes — the typed cache wrapper in
14/// `whatsapp-rust` handles serialization via serde.
15///
16/// # Namespaces
17///
18/// Each logical cache uses a unique namespace string (e.g., `"group"`,
19/// `"device"`, `"lid_pn_by_lid"`). Implementations should use this to
20/// partition keys — for example, a Redis implementation might prefix keys
21/// as `{namespace}:{key}`.
22///
23/// # Error handling
24///
25/// Cache operations are best-effort. The client falls back gracefully when
26/// cache reads fail (treats as miss) and logs warnings on write failures.
27/// Implementations should still return errors for observability.
28#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
29#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
30pub trait CacheStore: Send + Sync + 'static {
31    /// Retrieve a cached value by namespace and key.
32    async fn get(&self, namespace: &str, key: &str) -> anyhow::Result<Option<Vec<u8>>>;
33
34    /// Store a value with an optional TTL.
35    ///
36    /// When `ttl` is `None`, the entry should persist until explicitly deleted
37    /// or evicted by the implementation's own policy.
38    async fn set(
39        &self,
40        namespace: &str,
41        key: &str,
42        value: &[u8],
43        ttl: Option<Duration>,
44    ) -> anyhow::Result<()>;
45
46    /// Delete a single key from the given namespace.
47    async fn delete(&self, namespace: &str, key: &str) -> anyhow::Result<()>;
48
49    /// Delete all keys in a namespace.
50    async fn clear(&self, namespace: &str) -> anyhow::Result<()>;
51
52    /// Return the approximate number of entries in a namespace.
53    ///
54    /// Used only for diagnostics. Implementations that cannot cheaply
55    /// report counts should return `Ok(0)`.
56    async fn entry_count(&self, _namespace: &str) -> anyhow::Result<u64> {
57        Ok(0)
58    }
59}