tokio_cache/
async_cache.rs1use std::borrow::Borrow;
2use std::fmt::{self, Debug};
3use std::future::Future;
4use std::hash::Hash;
5use std::sync::Arc;
6
7use crate::core::{CacheCore, ExpireEntry};
8
9struct Never;
10
11impl<V> ExpireEntry<V> for Never {
12 fn is_fresh(&self, _: &V) -> bool {
13 true
14 }
15}
16
17#[derive(Clone)]
20pub struct AsyncCache<K, V>
21where
22 K: Hash + Eq + Clone,
23 V: Clone,
24{
25 core: Arc<CacheCore<K, V>>,
26}
27
28impl<K, V> AsyncCache<K, V>
29where
30 K: Hash + Eq + Clone,
31 V: Clone,
32{
33 pub fn new() -> Self {
34 AsyncCache {
35 core: Arc::new(CacheCore::new()),
36 }
37 }
38
39 pub fn read<BK>(&self, key: &BK) -> Option<V>
43 where
44 BK: Hash + Eq + ?Sized,
45 K: Borrow<BK>,
46 {
47 self.core.read(key, &Never)
48 }
49
50 pub async fn write<F, E>(&self, key: K, future: F) -> Result<V, E>
55 where
56 F: Future<Output = Result<V, E>>,
57 {
58 if let Some(value) = self.read(&key) {
59 return Ok(value)
60 }
61
62 self.core.write(key, future, &Never).await
63 }
64}
65
66impl<K, V> Debug for AsyncCache<K, V>
67where
68 K: Hash + Eq + Clone + Debug,
69 V: Clone + Debug,
70{
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 f.debug_struct("AsyncCache")
73 .field("entries", &self.core)
74 .finish()
75 }
76}
77
78impl<K, V> Default for AsyncCache<K, V>
79where
80 K: Hash + Eq + Clone + Debug,
81 V: Clone + Debug,
82{
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::AsyncCache;
91
92 #[tokio::test]
93 async fn insert_then_get_single_entry() {
94 let cache = AsyncCache::new();
95
96 assert_eq!(None, cache.read(&1));
97 assert_eq!(
98 Ok(2),
99 cache.write(1, async { Result::<_, ()>::Ok(2) }).await
100 );
101 assert_eq!(Some(2), cache.read(&1));
102 }
103
104 #[tokio::test]
105 async fn writing_twice_does_not_override() {
106 let cache = AsyncCache::new();
107
108 assert_eq!(None, cache.read(&1));
109 assert_eq!(
110 Ok(2),
111 cache.write(1, async { Result::<_, ()>::Ok(2) }).await
112 );
113 assert_eq!(Some(2), cache.read(&1));
114 assert_eq!(
115 Ok(2),
116 cache.write(1, async { Result::<_, ()>::Ok(3) }).await
117 );
118 assert_eq!(Some(2), cache.read(&1));
119 }
120}