use crate::core::{Finding, Severity};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScanReport {
pub findings: Vec<Finding>,
pub scanned_files: usize,
pub scanned_bytes: u64,
pub duration_ms: u64,
pub plugin_reports: Vec<PluginScanReport>,
pub warnings: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginScanReport {
pub plugin_name: String,
pub findings_count: usize,
pub duration_ms: u64,
}
impl ScanReport {
pub fn new() -> Self {
Self {
findings: Vec::new(),
scanned_files: 0,
scanned_bytes: 0,
duration_ms: 0,
plugin_reports: Vec::new(),
warnings: Vec::new(),
}
}
pub fn max_severity(&self) -> Severity {
self.findings
.iter()
.map(|f| f.severity)
.max()
.unwrap_or(Severity::Info)
}
pub fn count_by_severity(&self, severity: Severity) -> usize {
self.findings
.iter()
.filter(|f| f.severity == severity)
.count()
}
pub fn has_findings_at_or_above(&self, threshold: Severity) -> bool {
self.findings.iter().any(|f| f.severity >= threshold)
}
pub fn merge(&mut self, other: ScanReport) {
self.findings.extend(other.findings);
self.scanned_files += other.scanned_files;
self.scanned_bytes += other.scanned_bytes;
self.duration_ms += other.duration_ms;
self.plugin_reports.extend(other.plugin_reports);
self.warnings.extend(other.warnings);
}
}
impl Default for ScanReport {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Serialize)]
pub struct AcquisitionReport {
pub target: PathBuf,
pub scan_report: ScanReport,
pub sanitize_report: SanitizeReport,
pub has_history: bool,
pub head_commit: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SanitizeReport {
pub removed_hooks: Vec<String>,
pub removed_config_sections: Vec<String>,
pub removed_config_keys: Vec<String>,
pub removed_files: Vec<String>,
pub warnings: Vec<String>,
}