bgustscraper 0.2.0

Advanced semantic scraping engine with AI-driven compliance checks and legal terms validation
Documentation
use anyhow::{Result, Context};
use std::fs;
use std::path::Path;
use redb::{Database, TableDefinition};

const CACHE_TABLE: TableDefinition<&str, &str> = TableDefinition::new("web_cache");

pub struct LocalCache {
    db: Database,
}

impl LocalCache {
    pub fn new() -> Result<Self> {
        let cache_dir = Path::new("downloads");
        if !cache_dir.exists() {
            fs::create_dir_all(cache_dir).context("No se pudo crear el directorio downloads para la caché")?;
        }
        
        let db_path = cache_dir.join("cache.db");
        let db = Database::create(db_path).context("No se pudo iniciar la base de datos embebida redb")?;
        
        // Inicializar la tabla si no existe abriendo una transacción de escritura y confirmando
        let write_txn = db.begin_write()?;
        {
            let _table = write_txn.open_table(CACHE_TABLE)?;
        }
        write_txn.commit()?;

        Ok(Self { db })
    }

    pub fn get(&self, url: &str) -> Result<Option<String>> {
        let read_txn = self.db.begin_read()?;
        let table = read_txn.open_table(CACHE_TABLE)?;
        let value = table.get(url)?;
        
        if let Some(val_guard) = value {
            Ok(Some(val_guard.value().to_string()))
        } else {
            Ok(None)
        }
    }

    pub fn set(&self, url: &str, content: &str) -> Result<()> {
        let write_txn = self.db.begin_write()?;
        {
            let mut table = write_txn.open_table(CACHE_TABLE)?;
            table.insert(url, content)?;
        }
        write_txn.commit()?;
        Ok(())
    }
}