use std::{collections::HashMap, fs, path::Path};
use anyhow::{Context, Result};
use crate::rules::{Fix, Violation};
pub fn apply_fixes(violations: &[Violation]) -> Result<usize> {
let total_violations_with_fixes = violations.iter().filter(|v| !v.fixes.is_empty()).count();
let mut by_file: HashMap<&Path, Vec<&Fix>> = HashMap::new();
for violation in violations {
if !violation.fixes.is_empty() {
for fix in &violation.fixes {
by_file
.entry(violation.file.as_path())
.or_default()
.push(fix);
}
}
}
for (file_path, mut fixes) in by_file {
fixes.sort_by_key(|b| std::cmp::Reverse(b.start_byte));
let content = fs::read(file_path)
.with_context(|| format!("Failed to read file: {}", file_path.display()))?;
let mut modified_content = content;
for fix in fixes {
let mut new_content = Vec::new();
new_content.extend_from_slice(&modified_content[..fix.start_byte]);
new_content.extend_from_slice(fix.replacement.as_bytes());
new_content.extend_from_slice(&modified_content[fix.end_byte..]);
modified_content = new_content;
}
fs::write(file_path, modified_content)
.with_context(|| format!("Failed to write file: {}", file_path.display()))?;
}
Ok(total_violations_with_fixes)
}