use crate::formatters::Formatter;
use crate::utils::types::FormatResult;
use crate::{Language, Result};
use std::fs;
use std::path::Path;
use std::process::Command;
pub struct ScalaFormatter;
impl ScalaFormatter {
pub fn new() -> Self {
Self
}
}
impl Default for ScalaFormatter {
fn default() -> Self {
Self::new()
}
}
impl Formatter for ScalaFormatter {
fn name(&self) -> &str {
"scalafmt"
}
fn supported_languages(&self) -> &[Language] {
&[Language::Scala]
}
fn format(&self, path: &Path) -> Result<FormatResult> {
let original = fs::read_to_string(path).map_err(|e| {
crate::LintisError::formatter("scalafmt", path, format!("Failed to read file: {}", e))
})?;
let output = Command::new("scalafmt").arg(path).output().map_err(|e| {
crate::LintisError::formatter("scalafmt", path, format!("Failed to run: {}", e))
})?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Ok(FormatResult::error(
path.to_path_buf(),
format!("scalafmt failed: {}", stderr),
));
}
let new_content = fs::read_to_string(path).map_err(|e| {
crate::LintisError::formatter(
"scalafmt",
path,
format!("Failed to read formatted file: {}", e),
)
})?;
if original == new_content {
Ok(FormatResult::unchanged(path.to_path_buf()))
} else {
Ok(FormatResult::changed(path.to_path_buf()))
}
}
fn check(&self, path: &Path) -> Result<bool> {
let output = Command::new("scalafmt")
.args(["--check"])
.arg(path)
.output()
.map_err(|e| {
crate::LintisError::formatter("scalafmt", path, format!("Failed to run: {}", e))
})?;
Ok(!output.status.success())
}
fn is_available(&self) -> bool {
Command::new("scalafmt")
.arg("--version")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
}