use std::path::Path;
use thiserror::Error;
use crate::extract::{parse_files_to_ir, scan_and_build_ir, ExtractOptions};
use crate::pipeline::ScanOptions;
use crate::store::{GraphStore, InMemoryGraph, RefreshReport};
#[derive(Debug, Error)]
pub enum ProjectError {
#[error("scan/extract failed: {0}")]
Extract(#[from] crate::extract::ExtractError),
}
pub fn parse_project(root: &Path, scan: &ScanOptions) -> Result<InMemoryGraph, ProjectError> {
let extract_opts = ExtractOptions::from(&scan.graph);
let ir = scan_and_build_ir(root, &extract_opts, scan)?;
Ok(InMemoryGraph::from_ir(ir))
}
pub fn refresh_files(
graph: &mut InMemoryGraph,
root: &Path,
cleanup_targets: &[String],
parse_targets: &[String],
scan: &ScanOptions,
) -> Result<RefreshReport, ProjectError> {
let extract_opts = ExtractOptions::from(&scan.graph);
for path in cleanup_targets {
graph.remove_file(path);
}
let nodes_before = graph.node_count();
let edges_before = graph.edge_count();
if !parse_targets.is_empty() {
let delta = parse_files_to_ir(root, parse_targets, &extract_opts, scan)?;
graph.merge_ir(delta);
}
Ok(RefreshReport {
cleanup_targets: cleanup_targets.len(),
parse_targets: parse_targets.len(),
nodes_merged: graph.node_count().saturating_sub(nodes_before),
edges_merged: graph.edge_count().saturating_sub(edges_before),
})
}