use std::collections::HashMap;
use std::path::Path;
use rsigma_parser::lint::fix::apply_fixes_to_source;
use rsigma_parser::lint::{FileLintResult, LintWarning};
pub struct FixResult {
pub applied: usize,
pub failed: usize,
pub files_modified: usize,
}
fn collect_fixable_warnings(results: &[FileLintResult]) -> HashMap<&Path, Vec<&LintWarning>> {
let mut by_file: HashMap<&Path, Vec<&LintWarning>> = HashMap::new();
for result in results {
for w in &result.warnings {
if w.fix.is_some() {
by_file.entry(&result.path).or_default().push(w);
}
}
}
by_file
}
pub fn apply_fixes(results: &[FileLintResult]) -> FixResult {
let by_file = collect_fixable_warnings(results);
let mut total_applied = 0usize;
let mut total_failed = 0usize;
let mut files_modified = 0usize;
for (file_path, warnings) in &by_file {
let source = match std::fs::read_to_string(file_path) {
Ok(s) => s,
Err(e) => {
eprintln!(" cannot read {}: {e}", file_path.display());
total_failed += warnings.len();
continue;
}
};
let outcome = apply_fixes_to_source(&source, warnings);
total_failed += outcome.failed;
if outcome.fixed_source != source {
if let Err(e) = std::fs::write(file_path, &outcome.fixed_source) {
eprintln!(" cannot write {}: {e}", file_path.display());
total_failed += outcome.applied;
} else {
total_applied += outcome.applied;
files_modified += 1;
}
}
}
FixResult {
applied: total_applied,
failed: total_failed,
files_modified,
}
}