siftdb-core 0.2.2

High-performance grep-native database for code and text collections with regex support
Documentation
use crate::types::{FileHandle, HandleMetadata};
use anyhow::Result;
use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use std::path::Path;
use serde_json;
use crate::fst_index::PathFSTIndex;

/// Path index supporting both JSON (0.1) and FST (0.2) formats
#[derive(Serialize, Deserialize)]
pub struct PathIndex {
    pub paths: HashMap<String, FileHandle>,
    pub next_handle: FileHandle,
    #[serde(skip)]
    pub fst_index: Option<PathFSTIndex>, // 0.2 feature: FST-based fast path queries
}

impl PathIndex {
    pub fn new() -> Self {
        Self {
            paths: HashMap::new(),
            next_handle: 1,
            fst_index: None,
        }
    }
    
    pub fn add_path(&mut self, path: String) -> FileHandle {
        if let Some(&handle) = self.paths.get(&path) {
            return handle;
        }
        
        let handle = self.next_handle;
        self.paths.insert(path, handle);
        self.next_handle += 1;
        handle
    }
    
    pub fn get_handle(&self, path: &str) -> Option<FileHandle> {
        self.paths.get(path).copied()
    }
    
    pub fn get_path(&self, handle: FileHandle) -> Option<String> {
        self.paths.iter()
            .find(|(_, &h)| h == handle)
            .map(|(path, _)| path.clone())
    }
    
    pub fn write_to_file(&self, path: &Path) -> Result<()> {
        let json = serde_json::to_string_pretty(self)?;
        std::fs::write(path, json)?;
        Ok(())
    }
    
    pub fn read_from_file(path: &Path) -> Result<Self> {
        if !path.exists() {
            return Ok(Self::new());
        }
        let json = std::fs::read_to_string(path)?;
        let index = serde_json::from_str(&json)?;
        Ok(index)
    }
}

/// Handle metadata map
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HandlesMap {
    pub handles: HashMap<FileHandle, HandleMetadata>,
}

impl HandlesMap {
    pub fn new() -> Self {
        Self {
            handles: HashMap::new(),
        }
    }
    
    pub fn add_handle(&mut self, handle: FileHandle, metadata: HandleMetadata) {
        self.handles.insert(handle, metadata);
    }
    
    pub fn get_metadata(&self, handle: FileHandle) -> Option<&HandleMetadata> {
        self.handles.get(&handle)
    }
    
    pub fn write_to_file(&self, path: &Path) -> Result<()> {
        let json = serde_json::to_string_pretty(self)?;
        std::fs::write(path, json)?;
        Ok(())
    }
    
    pub fn read_from_file(path: &Path) -> Result<Self> {
        if !path.exists() {
            return Ok(Self::new());
        }
        let json = std::fs::read_to_string(path)?;
        let index = serde_json::from_str(&json)?;
        Ok(index)
    }
}

impl Default for PathIndex {
    fn default() -> Self {
        Self::new()
    }
}

impl Default for HandlesMap {
    fn default() -> Self {
        Self::new()
    }
}