1use std::fmt::Debug;
7use std::sync::Arc;
8
9use crate::tier::DynCacheTier;
10use crate::{CacheEntry, CacheTier, Error, SizeError};
11
12pub struct DynamicCache<K, V>(Arc<DynCacheTier<'static, K, V>>);
27
28impl<K, V> DynamicCache<K, V> {
29 pub fn new<T>(strategy: T) -> Self
31 where
32 T: CacheTier<K, V> + Send + Sync + 'static,
33 {
34 Self(DynCacheTier::new_arc(strategy))
35 }
36}
37
38impl<K, V> Debug for DynamicCache<K, V> {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 f.debug_struct("DynamicCache").finish()
41 }
42}
43
44impl<K, V> Clone for DynamicCache<K, V> {
45 fn clone(&self) -> Self {
46 Self(Arc::clone(&self.0))
47 }
48}
49
50impl<K: Send + Sync, V: Send> CacheTier<K, V> for DynamicCache<K, V> {
51 async fn get(&self, key: &K) -> Result<Option<CacheEntry<V>>, Error> {
52 self.0.get(key).await
53 }
54
55 async fn insert(&self, key: K, entry: CacheEntry<V>) -> Result<(), Error> {
56 self.0.insert(key, entry).await
57 }
58
59 async fn invalidate(&self, key: &K) -> Result<(), Error> {
60 self.0.invalidate(key).await
61 }
62
63 async fn clear(&self) -> Result<(), Error> {
64 self.0.clear().await
65 }
66
67 async fn len(&self) -> Result<u64, SizeError> {
68 self.0.len().await
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::MockCache;
76
77 #[cfg_attr(miri, ignore)]
78 #[tokio::test]
79 async fn clone_shares_state() {
80 let cache = MockCache::<String, i32>::new();
81 let dynamic = DynamicCache::new(cache);
82 let clone = dynamic.clone();
83
84 dynamic.insert("key".to_string(), CacheEntry::new(42)).await.unwrap();
85
86 let entry = clone.get(&"key".to_string()).await.unwrap().unwrap();
87 assert_eq!(*entry.value(), 42);
88 }
89}