1use anyhow::Result;
2use serde_json::to_value;
3use tokio::sync::Mutex;
4
5use crate::interfaces::Command;
6
7#[must_use]
8pub fn get_key(sql: &str, command: &Command) -> String {
9 use sha2::{Digest, Sha256};
10 let mut hasher = Sha256::new();
11 hasher.update(sql);
12 format!(
13 "{:x}.{}",
14 hasher.finalize(),
15 to_value(command).unwrap().as_str().unwrap()
16 )
17}
18
19pub async fn retrieve<F, Fut>(
20 cache: &Mutex<lru::LruCache<String, Vec<u8>>>,
21 sql: &str,
22 command: &Command,
23 persist: bool,
24 f: F,
25) -> Result<Vec<u8>>
26where
27 F: FnOnce() -> Fut,
28 Fut: std::future::Future<Output = Result<Vec<u8>>>,
29{
30 let key = get_key(sql, command);
31
32 if let Some(cached) = cache.lock().await.get(&key) {
33 tracing::debug!("Cache hit {}!", key);
34 return Ok(cached.clone());
35 }
36
37 let result = f().await?;
38
39 if persist {
40 cache.lock().await.put(key, result.clone());
41 }
42
43 Ok(result)
44}