crates_docs/tools/docs/
cache.rs1use crate::cache::Cache;
4use std::sync::Arc;
5use std::time::Duration;
6
7#[derive(Clone)]
9pub struct DocCache {
10 cache: Arc<dyn Cache>,
11}
12
13impl DocCache {
14 pub fn new(cache: Arc<dyn Cache>) -> Self {
16 Self { cache }
17 }
18
19 pub async fn get_crate_docs(&self, crate_name: &str, version: Option<&str>) -> Option<String> {
21 let key = Self::crate_cache_key(crate_name, version);
22 self.cache.get(&key).await
23 }
24
25 pub async fn set_crate_docs(
31 &self,
32 crate_name: &str,
33 version: Option<&str>,
34 content: String,
35 ) -> crate::error::Result<()> {
36 let key = Self::crate_cache_key(crate_name, version);
37 self.cache
38 .set(key, content, Some(Duration::from_secs(3600)))
39 .await
40 }
41
42 pub async fn get_search_results(&self, query: &str, limit: u32) -> Option<String> {
44 let key = Self::search_cache_key(query, limit);
45 self.cache.get(&key).await
46 }
47
48 pub async fn set_search_results(
54 &self,
55 query: &str,
56 limit: u32,
57 content: String,
58 ) -> crate::error::Result<()> {
59 let key = Self::search_cache_key(query, limit);
60 self.cache
61 .set(key, content, Some(Duration::from_secs(300)))
62 .await }
64
65 pub async fn get_item_docs(
67 &self,
68 crate_name: &str,
69 item_path: &str,
70 version: Option<&str>,
71 ) -> Option<String> {
72 let key = Self::item_cache_key(crate_name, item_path, version);
73 self.cache.get(&key).await
74 }
75
76 pub async fn set_item_docs(
82 &self,
83 crate_name: &str,
84 item_path: &str,
85 version: Option<&str>,
86 content: String,
87 ) -> crate::error::Result<()> {
88 let key = Self::item_cache_key(crate_name, item_path, version);
89 self.cache
90 .set(key, content, Some(Duration::from_secs(1800)))
91 .await }
93
94 pub async fn clear(&self) -> crate::error::Result<()> {
100 self.cache.clear().await
101 }
102
103 fn crate_cache_key(crate_name: &str, version: Option<&str>) -> String {
105 if let Some(ver) = version {
106 format!("crate:{crate_name}:{ver}")
107 } else {
108 format!("crate:{crate_name}")
109 }
110 }
111
112 fn search_cache_key(query: &str, limit: u32) -> String {
114 format!("search:{query}:{limit}")
115 }
116
117 fn item_cache_key(crate_name: &str, item_path: &str, version: Option<&str>) -> String {
119 if let Some(ver) = version {
120 format!("item:{crate_name}:{ver}:{item_path}")
121 } else {
122 format!("item:{crate_name}:{item_path}")
123 }
124 }
125}
126
127impl Default for DocCache {
128 fn default() -> Self {
129 let cache = Arc::new(crate::cache::memory::MemoryCache::new(1000));
130 Self::new(cache)
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137 use crate::cache::memory::MemoryCache;
138
139 #[tokio::test]
140 async fn test_doc_cache() {
141 let memory_cache = MemoryCache::new(100);
142 let cache = Arc::new(memory_cache);
143 let doc_cache = DocCache::new(cache);
144
145 doc_cache
147 .set_crate_docs("serde", Some("1.0"), "Test docs".to_string())
148 .await
149 .expect("set_crate_docs should succeed");
150 let cached = doc_cache.get_crate_docs("serde", Some("1.0")).await;
151 assert_eq!(cached, Some("Test docs".to_string()));
152
153 doc_cache
155 .set_search_results("web framework", 10, "Search results".to_string())
156 .await
157 .expect("set_search_results should succeed");
158 let search_cached = doc_cache.get_search_results("web framework", 10).await;
159 assert_eq!(search_cached, Some("Search results".to_string()));
160
161 doc_cache
163 .set_item_docs(
164 "serde",
165 "serde::Serialize",
166 Some("1.0"),
167 "Item docs".to_string(),
168 )
169 .await
170 .expect("set_item_docs should succeed");
171 let item_cached = doc_cache
172 .get_item_docs("serde", "serde::Serialize", Some("1.0"))
173 .await;
174 assert_eq!(item_cached, Some("Item docs".to_string()));
175
176 doc_cache.clear().await.expect("clear should succeed");
178 let cleared = doc_cache.get_crate_docs("serde", Some("1.0")).await;
179 assert_eq!(cleared, None);
180 }
181
182 #[test]
183 fn test_cache_key_generation() {
184 assert_eq!(DocCache::crate_cache_key("serde", None), "crate:serde");
185 assert_eq!(
186 DocCache::crate_cache_key("serde", Some("1.0")),
187 "crate:serde:1.0"
188 );
189
190 assert_eq!(
191 DocCache::search_cache_key("web framework", 10),
192 "search:web framework:10"
193 );
194
195 assert_eq!(
196 DocCache::item_cache_key("serde", "Serialize", None),
197 "item:serde:Serialize"
198 );
199 assert_eq!(
200 DocCache::item_cache_key("serde", "Serialize", Some("1.0")),
201 "item:serde:1.0:Serialize"
202 );
203 }
204}