fn load_source_from_sqlite(db_path: &Path, file_path: &str, start_line: usize) -> Option<String> {
let conn = super::sqlite_backend::open_db(db_path).ok()?;
let src = super::sqlite_backend::load_source_by_location(&conn, file_path, start_line).ok()?;
if src.is_empty() {
None
} else {
Some(src)
}
}
fn load_source_from_file(file_path: &str, start_line: usize, end_line: usize) -> Option<String> {
if end_line == 0 || start_line == 0 {
return None;
}
let content = std::fs::read_to_string(file_path).ok()?;
let lines: Vec<&str> = content.lines().collect();
let start = start_line.saturating_sub(1);
let end = end_line.min(lines.len());
if start < end {
Some(lines[start..end].join("\n"))
} else {
None
}
}
struct MtimeReuseResult {
functions: Vec<FunctionEntry>,
checksum: String,
coverage_off: bool,
}
fn check_mtime_reuse(
path: &Path,
relative_path: &str,
index_built_at: &Option<std::time::SystemTime>,
existing: &AgentContextIndex,
) -> Option<MtimeReuseResult> {
let built_at = index_built_at.as_ref()?;
let mtime = fs::metadata(path).ok()?.modified().ok()?;
if mtime >= *built_at {
return None;
}
let checksum = existing.manifest.file_checksums.get(relative_path)?.clone();
let funcs = existing
.file_index
.get(relative_path)
.map(|indices| {
indices
.iter()
.map(|&idx| existing.functions[idx].clone())
.collect()
})
.unwrap_or_default();
let coverage_off = existing.coverage_off_files.contains(relative_path);
Some(MtimeReuseResult {
functions: funcs,
checksum,
coverage_off,
})
}
fn parse_built_at(built_at: &str) -> Option<std::time::SystemTime> {
let dt = chrono::DateTime::parse_from_rfc3339(built_at).ok()?;
let secs = dt.timestamp();
if secs < 0 {
return None;
}
Some(std::time::UNIX_EPOCH + std::time::Duration::from_secs(secs as u64))
}
fn project_prefix(path: &str) -> &str {
path.split('/').next().unwrap_or(path)
}