use super::types::FormatResult;
use super::utils::ensure_rustfmt_installed;
use crate::{Error, Result};
use std::path::Path;
use tokio::fs;
pub async fn check_formatting(project_path: &Path) -> Result<FormatResult> {
ensure_rustfmt_installed().await?;
let output = tokio::process::Command::new("cargo")
.args(&["fmt", "--", "--check"])
.current_dir(project_path)
.output()
.await
.map_err(|e| Error::process(format!("Failed to run rustfmt: {}", e)))?;
let formatted = output.status.success();
let stderr = String::from_utf8_lossy(&output.stderr);
Ok(FormatResult {
formatted,
unformatted_files: if formatted {
vec![]
} else {
vec![format!("Multiple files need formatting (see: {})", stderr)]
},
suggestions: vec![],
})
}
pub async fn auto_format(project_path: &Path) -> Result<()> {
ensure_rustfmt_installed().await?;
let status = tokio::process::Command::new("cargo")
.args(&["fmt", "--all"])
.current_dir(project_path)
.status()
.await
.map_err(|e| Error::process(format!("Failed to run cargo fmt: {}", e)))?;
if !status.success() {
return Err(Error::process("Formatting failed".to_string()));
}
Ok(())
}
pub async fn get_format_diff(project_path: &Path) -> Result<String> {
ensure_rustfmt_installed().await?;
let output = tokio::process::Command::new("cargo")
.args(&["fmt", "--", "--check", "--print-diff"])
.current_dir(project_path)
.output()
.await
.map_err(|e| Error::process(format!("Failed to get format diff: {}", e)))?;
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
pub async fn apply_rustfmt_config(project_path: &Path) -> Result<()> {
let config_content = r#"# Ferrous Forge rustfmt configuration
max_width = 100
tab_spaces = 4
newline_style = "Unix"
use_small_heuristics = "Default"
edition = "2021"
"#;
let config_path = project_path.join("rustfmt.toml");
fs::write(&config_path, config_content).await?;
Ok(())
}