pagesift_api/types/
asset_cache.rs1use std::collections::HashMap;
3use std::sync::{Arc, Mutex};
4
5use tokio::sync::OnceCell;
6
7use super::Attachment;
8
9#[derive(Debug, Clone, Default)]
11pub struct AssetFetchCache(Arc<Mutex<HashMap<String, Arc<OnceCell<Attachment>>>>>);
12
13impl PartialEq for AssetFetchCache {
14 fn eq(&self, other: &Self) -> bool {
15 Arc::ptr_eq(&self.0, &other.0)
16 }
17}
18
19impl AssetFetchCache {
20 pub fn entry(&self, url: &str) -> Option<Arc<OnceCell<Attachment>>> {
22 let mut entries = self.0.lock().unwrap_or_else(|e| e.into_inner());
23 if let Some(cell) = entries.get(url) {
24 return Some(cell.clone());
25 }
26 if entries.len() >= 32 {
27 return None;
28 }
29 let cell = Arc::new(OnceCell::new());
30 entries.insert(url.to_owned(), cell.clone());
31 Some(cell)
32 }
33
34 pub fn discard(&self, url: &str, cell: &Arc<OnceCell<Attachment>>) {
35 let mut entries = self.0.lock().unwrap_or_else(|e| e.into_inner());
36 if entries
37 .get(url)
38 .is_some_and(|existing| Arc::ptr_eq(existing, cell))
39 {
40 entries.remove(url);
41 }
42 }
43
44 pub fn seed(&self, url: &str, attachment: Attachment) {
46 if attachment.bytes > 512 * 1024 || attachment.data.is_none() {
47 return;
48 }
49 if let Some(cell) = self.entry(url) {
50 let _ = cell.set(attachment);
51 }
52 }
53}