pub struct ValidateResult {
pub fixed_content: String,
pub warnings: Vec<String>,
pub was_fixed: bool,
pub rejected: bool,
}
pub async fn validate_and_fix(
content: &str,
_file_path: &str,
_new_string: &str,
_original_content: &str,
) -> ValidateResult {
let warnings: Vec<String> = Vec::new();
let current = content.to_string();
if !warnings.is_empty() {
return ValidateResult {
fixed_content: current,
warnings,
was_fixed: false,
rejected: true,
};
}
ValidateResult {
fixed_content: current,
warnings: vec![],
was_fixed: false,
rejected: false,
}
}
pub async fn post_edit_syntax_check(file_path: &str) -> String {
let ext = file_path.rsplit('.').next().unwrap_or("");
let cmd = match ext {
"js" | "mjs" | "cjs" => Some(("node", vec!["--check".to_string(), file_path.to_string()])),
"json" => {
return match tokio::fs::read_to_string(file_path).await {
Ok(content) => {
if serde_json::from_str::<serde_json::Value>(&content).is_err() {
format!(
"\n\u{26a0} SYNTAX ERROR: {} is not valid JSON. Fix before proceeding.",
file_path
)
} else {
String::new()
}
}
Err(_) => String::new(),
};
}
"ts" | "tsx" => {
return String::new();
}
"vue" | "svelte" => {
let mut warnings = Vec::new();
if let Ok(content) = tokio::fs::read_to_string(file_path).await {
if let Some(script_start) = content.find("<script") {
let script_end = content.find("</script>").unwrap_or(content.len());
let script = &content[script_start..script_end];
let backtick_count = script.chars().filter(|c| *c == '`').count();
if backtick_count % 2 != 0 {
warnings.push(format!(
"Unclosed template string (`) in <script> — {} backticks found (odd). \
Use regular strings ('') for data containing backticks.",
backtick_count
));
}
}
}
if warnings.is_empty() {
return String::new();
}
return format!("\n⚠ VUE SYNTAX: {}", warnings.join("; "));
}
"py" => Some((
"python3",
vec![
"-m".to_string(),
"py_compile".to_string(),
file_path.to_string(),
],
)),
_ => None,
};
if let Some((program, args)) = cmd {
let mut command = tokio::process::Command::new(program);
command.args(&args);
crate::process_utils::suppress_console_window(&mut command);
match command.output().await {
Ok(output) if !output.status.success() => {
let stderr = String::from_utf8_lossy(&output.stderr);
let first_lines: String = stderr.lines().take(3).collect::<Vec<_>>().join("\n");
format!("\n\u{26a0} SYNTAX ERROR in {}:\n{}", file_path, first_lines)
}
_ => String::new(),
}
} else {
String::new()
}
}