1use std::path::PathBuf;
2
3pub use smart_cache_macro::cached;
4
5use eyre::Result;
6use once_cell::sync::Lazy;
7use redb::{Database, TableDefinition};
8use tracing::{debug, trace};
9
10const CACHE_TABLE: TableDefinition<&[u8], &[u8]> = TableDefinition::new("cache");
12
13static DB: Lazy<Database> = Lazy::new(|| {
14 let cache_dir = dirs::cache_dir()
15 .unwrap_or_else(|| PathBuf::from(".cache"))
16 .join("smart-cache");
17 std::fs::create_dir_all(&cache_dir).expect("failed to create cache directory");
18
19 let db_path = cache_dir.join("cache.redb");
20 Database::create(db_path).expect("failed to create cache database")
21});
22
23#[doc(hidden)]
25pub fn get_cached(key_bytes: &[u8]) -> Option<Vec<u8>> {
26 trace!("Attempting cache lookup");
27
28 match DB.begin_read() {
29 Ok(txn) => match txn.open_table(CACHE_TABLE) {
30 Ok(table) => match table.get(key_bytes) {
31 Ok(Some(value)) => {
32 debug!("Cache hit");
33 Some(value.value().to_vec())
34 }
35 Ok(None) => {
36 debug!("Cache miss");
37 None
38 }
39 Err(e) => {
40 debug!("Cache error: {}", e);
41 None
42 }
43 },
44 Err(e) => {
45 debug!("Failed to open table: {}", e);
46 None
47 }
48 },
49 Err(e) => {
50 debug!("Failed to begin read transaction: {}", e);
51 None
52 }
53 }
54}
55
56#[doc(hidden)]
58pub fn set_cached(key: &[u8], value: &[u8]) -> Result<()> {
59 trace!("Caching value");
60
61 let write_txn = DB.begin_write()?;
62 {
63 let mut table = write_txn.open_table(CACHE_TABLE)?;
64 table.insert(key, value)?;
65 }
66 write_txn.commit()?;
67
68 debug!("Successfully cached value");
69 Ok(())
70}