use crate::IndexResult;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IndexMetadata {
pub version: u32,
pub data_source: DataSource,
pub symbol_count: u32,
pub file_count: u32,
pub last_modified: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub indexed_paths: Option<Vec<PathBuf>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DataSource {
Tantivy {
path: PathBuf,
doc_count: u64,
timestamp: u64,
},
Fresh,
}
impl Default for IndexMetadata {
fn default() -> Self {
Self {
version: 1,
data_source: DataSource::Fresh,
symbol_count: 0,
file_count: 0,
last_modified: crate::indexing::get_utc_timestamp(),
indexed_paths: None,
}
}
}
impl IndexMetadata {
pub fn new() -> Self {
Self::default()
}
pub fn update_counts(&mut self, symbol_count: u32, file_count: u32) {
self.symbol_count = symbol_count;
self.file_count = file_count;
self.last_modified = crate::indexing::get_utc_timestamp();
}
pub fn update_indexed_paths(&mut self, paths: Vec<PathBuf>) {
self.indexed_paths = Some(paths);
self.last_modified = crate::indexing::get_utc_timestamp();
}
pub fn save(&self, base_path: &Path) -> IndexResult<()> {
let metadata_path = base_path.join("index.meta");
let json = serde_json::to_string_pretty(self).map_err(|e| {
crate::IndexError::General(format!("Failed to serialize metadata: {e}"))
})?;
fs::write(&metadata_path, json).map_err(|e| crate::IndexError::FileWrite {
path: metadata_path,
source: e,
})?;
Ok(())
}
pub fn load(base_path: &Path) -> IndexResult<Self> {
let metadata_path = base_path.join("index.meta");
if !metadata_path.exists() {
return Ok(Self::new());
}
let json = fs::read_to_string(&metadata_path).map_err(|e| crate::IndexError::FileRead {
path: metadata_path.clone(),
source: e,
})?;
serde_json::from_str(&json)
.map_err(|e| crate::IndexError::General(format!("Failed to parse metadata: {e}")))
}
pub fn display_source(&self) {
match &self.data_source {
DataSource::Tantivy {
path, doc_count, ..
} => {
eprintln!(
"Loaded from Tantivy index: {} ({} documents)",
path.display(),
doc_count
);
}
DataSource::Fresh => {
eprintln!("Created fresh index");
}
}
eprintln!(
"Index contains {} symbols from {} files",
self.symbol_count, self.file_count
);
}
}