use crate::generator::context::GeneratorContext;
use anyhow::Result;
use std::path::Path;
use std::process::Stdio;
use tokio::process::Command as TokioCommand;
pub struct MermaidFixer;
impl MermaidFixer {
pub async fn is_available() -> bool {
match TokioCommand::new("mermaid-fixer")
.arg("--version")
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.await
{
Ok(status) => status.success(),
Err(_) => false,
}
}
pub async fn fix_mermaid_charts(
context: &GeneratorContext,
target_dir: &Path,
) -> Result<()> {
if !Self::is_available().await {
println!("⚠️ 警告: mermaid-fixer 未安装或不可用,跳过mermaid图表修复");
println!("💡 提示: 请运行 'cargo install mermaid-fixer' 来安装mermaid修复工具");
return Ok(());
}
println!("🔧 开始修复mermaid图表...");
let mut cmd = TokioCommand::new("mermaid-fixer");
cmd.arg("--directory").arg(target_dir);
let llm_config = &context.config.llm;
cmd.arg("--llm-model").arg(&llm_config.model_powerful);
if !llm_config.api_key.is_empty() {
cmd.arg("--llm-api-key").arg(&llm_config.api_key);
}
if !llm_config.api_base_url.is_empty() {
cmd.arg("--llm-base-url").arg(&llm_config.api_base_url);
}
cmd.arg("--verbose");
cmd.stdout(Stdio::inherit());
cmd.stderr(Stdio::inherit());
println!("🚀 执行命令(只显示部分信息): mermaid-fixer --directory {} --llm-model {} --verbose",
target_dir.display(),
llm_config.model_powerful);
match cmd.status().await {
Ok(status) => {
if status.success() {
println!("✅ mermaid图表修复完成");
} else {
println!("⚠️ mermaid-fixer执行完成,但返回非零状态码: {}",
status.code().unwrap_or(-1));
println!("💡 这可能表示某些图表无法修复,但不会影响后续流程");
}
}
Err(e) => {
println!("⚠️ 执行mermaid-fixer时出错: {}", e);
println!("💡 mermaid图表修复失败,但不会阻塞后续流程");
}
}
Ok(())
}
pub async fn auto_fix_after_output(context: &GeneratorContext) -> Result<()> {
let output_dir = &context.config.output_path;
if !output_dir.exists() {
println!("⚠️ 输出目录不存在,跳过mermaid图表修复");
return Ok(());
}
Self::fix_mermaid_charts(context, output_dir).await
}
}