use crate::config::ProjectConfig;
use crate::detectors::FileContentCache;
use crate::graph::GraphQuery;
use crate::models::Finding;
use anyhow::Result;
use std::collections::HashSet;
use std::path::{Path, PathBuf};
use std::sync::Arc;
pub struct PostprocessInput<'a> {
pub findings: Vec<Finding>,
pub project_config: &'a ProjectConfig,
pub graph: &'a dyn GraphQuery,
pub all_files: &'a [PathBuf],
pub repo_path: &'a Path,
pub verify: bool,
pub bypass_set: HashSet<String>,
pub file_cache: Option<Arc<FileContentCache>>,
}
pub struct PostprocessStats {
pub input_count: usize,
pub output_count: usize,
pub suppressed: usize,
pub excluded: usize,
pub deduped: usize,
pub fp_filtered: usize,
pub security_downgraded: usize,
}
pub struct PostprocessOutput {
pub findings: Vec<Finding>,
pub stats: PostprocessStats,
}
pub fn postprocess_stage(input: PostprocessInput) -> Result<PostprocessOutput> {
let input_count = input.findings.len();
let mut findings = input.findings;
let params = crate::cli::analyze::postprocess::PostprocessParams {
project_config: input.project_config,
all_files: input.all_files,
graph: input.graph,
repo_path: input.repo_path,
bypass_set: &input.bypass_set,
verify: input.verify,
file_cache: input.file_cache.as_ref(),
};
let summary = crate::cli::analyze::postprocess::postprocess_findings(&mut findings, ¶ms);
let output_count = findings.len();
let total_removed = input_count.saturating_sub(output_count);
Ok(PostprocessOutput {
findings,
stats: PostprocessStats {
input_count,
output_count,
suppressed: 0, excluded: 0,
deduped: 0,
fp_filtered: total_removed,
security_downgraded: summary.security_downgraded,
},
})
}