use std::collections::HashSet;
use std::fs;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;
use crate::error::Result;
const INDEXED_COMMITS_FILE: &str = ".indexed_commits";
pub fn load_indexed_commits(agit_dir: &Path) -> Result<HashSet<String>> {
let index_path = agit_dir.join("search_index");
let state_file = index_path.join(INDEXED_COMMITS_FILE);
if !state_file.exists() {
return Ok(HashSet::new());
}
let file = fs::File::open(&state_file)?;
let reader = BufReader::new(file);
let mut commits = HashSet::new();
for line in reader.lines() {
let line = line?;
let hash = line.trim();
if !hash.is_empty() {
commits.insert(hash.to_string());
}
}
Ok(commits)
}
pub fn save_indexed_commits(agit_dir: &Path, commits: &HashSet<String>) -> Result<()> {
let index_path = agit_dir.join("search_index");
fs::create_dir_all(&index_path)?;
let state_file = index_path.join(INDEXED_COMMITS_FILE);
let mut file = fs::File::create(&state_file)?;
for hash in commits {
writeln!(file, "{}", hash)?;
}
Ok(())
}
pub fn mark_commit_indexed(agit_dir: &Path, hash: &str) -> Result<()> {
let mut commits = load_indexed_commits(agit_dir)?;
commits.insert(hash.to_string());
save_indexed_commits(agit_dir, &commits)
}
pub fn is_index_healthy(agit_dir: &Path) -> bool {
let index_path = agit_dir.join("search_index");
if !index_path.exists() {
return false;
}
let meta_file = index_path.join("meta.json");
meta_file.exists()
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
#[test]
fn test_load_empty() {
let temp_dir = TempDir::new().unwrap();
let agit_dir = temp_dir.path().join(".agit");
fs::create_dir_all(&agit_dir).unwrap();
let commits = load_indexed_commits(&agit_dir).unwrap();
assert!(commits.is_empty());
}
#[test]
fn test_save_and_load() {
let temp_dir = TempDir::new().unwrap();
let agit_dir = temp_dir.path().join(".agit");
fs::create_dir_all(&agit_dir).unwrap();
let mut commits = HashSet::new();
commits.insert("abc123".to_string());
commits.insert("def456".to_string());
save_indexed_commits(&agit_dir, &commits).unwrap();
let loaded = load_indexed_commits(&agit_dir).unwrap();
assert_eq!(commits, loaded);
}
#[test]
fn test_mark_commit_indexed() {
let temp_dir = TempDir::new().unwrap();
let agit_dir = temp_dir.path().join(".agit");
fs::create_dir_all(&agit_dir).unwrap();
mark_commit_indexed(&agit_dir, "abc123").unwrap();
mark_commit_indexed(&agit_dir, "def456").unwrap();
let commits = load_indexed_commits(&agit_dir).unwrap();
assert!(commits.contains("abc123"));
assert!(commits.contains("def456"));
}
#[test]
fn test_is_index_healthy() {
let temp_dir = TempDir::new().unwrap();
let agit_dir = temp_dir.path().join(".agit");
fs::create_dir_all(&agit_dir).unwrap();
assert!(!is_index_healthy(&agit_dir));
let index_path = agit_dir.join("search_index");
fs::create_dir_all(&index_path).unwrap();
assert!(!is_index_healthy(&agit_dir));
fs::write(index_path.join("meta.json"), "{}").unwrap();
assert!(is_index_healthy(&agit_dir));
}
}