impactsense_parser/
project.rs1use std::path::Path;
4
5use thiserror::Error;
6
7use crate::extract::{parse_files_to_ir, scan_and_build_ir, ExtractOptions};
8use crate::pipeline::ScanOptions;
9use crate::store::{GraphStore, InMemoryGraph, RefreshReport};
10
11#[derive(Debug, Error)]
12pub enum ProjectError {
13 #[error("scan/extract failed: {0}")]
14 Extract(#[from] crate::extract::ExtractError),
15}
16
17pub fn parse_project(root: &Path, scan: &ScanOptions) -> Result<InMemoryGraph, ProjectError> {
19 let extract_opts = ExtractOptions::from(&scan.graph);
20 let ir = scan_and_build_ir(root, &extract_opts, scan)?;
21 Ok(InMemoryGraph::from_ir(ir))
22}
23
24pub fn refresh_files(
26 graph: &mut InMemoryGraph,
27 root: &Path,
28 cleanup_targets: &[String],
29 parse_targets: &[String],
30 scan: &ScanOptions,
31) -> Result<RefreshReport, ProjectError> {
32 let extract_opts = ExtractOptions::from(&scan.graph);
33
34 for path in cleanup_targets {
35 graph.remove_file(path);
36 }
37
38 let nodes_before = graph.node_count();
39 let edges_before = graph.edge_count();
40
41 if !parse_targets.is_empty() {
42 let delta = parse_files_to_ir(root, parse_targets, &extract_opts, scan)?;
43 graph.merge_ir(delta);
44 }
45
46 Ok(RefreshReport {
47 cleanup_targets: cleanup_targets.len(),
48 parse_targets: parse_targets.len(),
49 nodes_merged: graph.node_count().saturating_sub(nodes_before),
50 edges_merged: graph.edge_count().saturating_sub(edges_before),
51 })
52}