atproto blogging
1//! Platform-specific TTL cache implementations.
2//!
3//! Provides a unified API over mini-moka-wasm's sync (native) and unsync (WASM) caches.
4//! Native uses the sync cache (thread-safe).
5//! WASM uses the unsync cache wrapped in Arc<Mutex<>> (single-threaded but needs interior mutability).
6
7#[cfg(not(target_arch = "wasm32"))]
8mod native {
9 use std::time::Duration;
10
11 pub type Cache<K, V> = mini_moka_wasm::sync::Cache<K, V>;
12
13 pub fn new_cache<K, V>(max_capacity: u64, ttl: Duration) -> Cache<K, V>
14 where
15 K: std::hash::Hash + Eq + Send + Sync + 'static,
16 V: Clone + Send + Sync + 'static,
17 {
18 mini_moka_wasm::sync::Cache::builder()
19 .max_capacity(max_capacity)
20 .time_to_live(ttl)
21 .build()
22 }
23
24 pub fn get<K, V>(cache: &Cache<K, V>, key: &K) -> Option<V>
25 where
26 K: std::hash::Hash + Eq + Send + Sync + 'static,
27 V: Clone + Send + Sync + 'static,
28 {
29 cache.get(key)
30 }
31
32 pub fn insert<K, V>(cache: &Cache<K, V>, key: K, value: V)
33 where
34 K: std::hash::Hash + Eq + Send + Sync + 'static,
35 V: Clone + Send + Sync + 'static,
36 {
37 cache.insert(key, value);
38 }
39
40 #[allow(dead_code)]
41 pub fn iter<K, V>(cache: &Cache<K, V>) -> Vec<V>
42 where
43 K: std::hash::Hash + Eq + Send + Sync + 'static,
44 V: Clone + Send + Sync + 'static,
45 {
46 cache.iter().map(|entry| entry.value().clone()).collect()
47 }
48}
49
50#[cfg(target_arch = "wasm32")]
51mod wasm {
52 use std::sync::{Arc, Mutex};
53 use std::time::Duration;
54
55 pub type Cache<K, V> = Arc<Mutex<mini_moka_wasm::unsync::Cache<K, V>>>;
56
57 pub fn new_cache<K, V>(max_capacity: u64, ttl: Duration) -> Cache<K, V>
58 where
59 K: std::hash::Hash + Eq + 'static,
60 V: Clone + 'static,
61 {
62 Arc::new(Mutex::new(
63 mini_moka_wasm::unsync::Cache::builder()
64 .max_capacity(max_capacity)
65 .time_to_live(ttl)
66 .build(),
67 ))
68 }
69
70 pub fn get<K, V>(cache: &Cache<K, V>, key: &K) -> Option<V>
71 where
72 K: std::hash::Hash + Eq + 'static,
73 V: Clone + 'static,
74 {
75 cache.lock().unwrap().get(key).cloned()
76 }
77
78 pub fn insert<K, V>(cache: &Cache<K, V>, key: K, value: V)
79 where
80 K: std::hash::Hash + Eq + 'static,
81 V: Clone + 'static,
82 {
83 cache.lock().unwrap().insert(key, value);
84 }
85
86 #[allow(dead_code)]
87 pub fn iter<K, V>(cache: &Cache<K, V>) -> Vec<V>
88 where
89 K: std::hash::Hash + Eq + 'static,
90 V: Clone + 'static,
91 {
92 cache
93 .lock()
94 .unwrap()
95 .iter()
96 .map(|(_, v)| v.clone())
97 .collect()
98 }
99}
100
101#[cfg(not(target_arch = "wasm32"))]
102pub use native::*;
103
104#[cfg(target_arch = "wasm32")]
105pub use wasm::*;
106
107/// Create a new cache with the given capacity and TTL.
108///
109/// This is a convenience re-export of `new_cache` for documentation purposes.
110/// The actual implementation is platform-specific.
111///
112/// # Example
113///
114/// ```ignore
115/// use weaver_common::cache;
116/// use std::time::Duration;
117///
118/// let cache = cache::new_cache::<String, String>(100, Duration::from_secs(3600));
119/// cache::insert(&cache, "key".to_string(), "value".to_string());
120/// assert_eq!(cache::get(&cache, &"key".to_string()), Some("value".to_string()));
121/// ```
122#[doc(hidden)]
123pub fn _doc_example() {}