Skip to main content

impactsense_parser/
extract.rs

1//! Pure extraction from parsed files into [`ProjectIr`] (no Neo4j).
2
3use std::path::Path;
4
5use thiserror::Error;
6
7use crate::graph::{build_project_ir, GraphPersistenceOptions};
8use crate::ir::ProjectIr;
9use crate::pipeline::ScanOptions;
10use crate::scanner::{scan_and_parse, FileScanConfig, ScannerError};
11
12pub use crate::graph::ExtractOptions;
13
14impl From<&ScanOptions> for crate::graph::ExtractOptions {
15    fn from(opts: &ScanOptions) -> Self {
16        Self {
17            verbose_imports: opts.graph.verbose_imports,
18            max_parse_warnings_per_file: opts.graph.max_parse_warnings_per_file,
19        }
20    }
21}
22
23impl From<&GraphPersistenceOptions> for crate::graph::ExtractOptions {
24    fn from(opts: &GraphPersistenceOptions) -> Self {
25        Self {
26            verbose_imports: opts.verbose_imports,
27            max_parse_warnings_per_file: opts.max_parse_warnings_per_file,
28        }
29    }
30}
31
32#[derive(Debug, Error)]
33pub enum ExtractError {
34    #[error("scan/parse failed: {0}")]
35    Scanner(#[from] ScannerError),
36}
37
38/// Build a full project IR from an already-parsed file batch.
39pub fn build_project_ir_from_files(
40    root: &Path,
41    files: &[crate::scanner::ParsedFile],
42    options: &ExtractOptions,
43) -> ProjectIr {
44    build_project_ir(root, files, options)
45}
46
47/// Scan a repository root and build project IR.
48pub fn scan_and_build_ir(
49    root: &Path,
50    options: &ExtractOptions,
51    scan: &ScanOptions,
52) -> Result<ProjectIr, ExtractError> {
53    let mut config = FileScanConfig::new(root);
54    config.follow_symlinks = scan.follow_symlinks;
55    config.max_file_size = scan.max_file_size;
56    let files = scan_and_parse(&config)?;
57    Ok(build_project_ir_from_files(root, &files, options))
58}
59
60/// Parse specific targets and build IR delta (incremental).
61pub fn parse_files_to_ir(
62    root: &Path,
63    parse_targets: &[String],
64    options: &ExtractOptions,
65    scan: &ScanOptions,
66) -> Result<ProjectIr, ExtractError> {
67    let mut config = FileScanConfig::new(root);
68    config.follow_symlinks = scan.follow_symlinks;
69    config.max_file_size = scan.max_file_size;
70    let paths: Vec<_> = parse_targets.iter().map(std::path::PathBuf::from).collect();
71    let files = crate::scanner_incremental::scan_and_parse_incremental_vector(&config, &paths)?;
72    Ok(build_project_ir_from_files(root, &files, options))
73}