smart_cache/
lib.rs

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
10// Define the table that will store our cache entries
11const 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/// Internal function used by the macro to get a cached value
24#[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/// Internal function used by the macro to set a cached value
57#[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}