deepwiki-rs 1.2.6

deepwiki-rs(also known as Litho) is a high-performance automatic generation engine for C4 architecture documentation, developed using Rust. It can intelligently analyze project structures, identify core components, parse dependency relationships, and leverage large language models (LLMs) to automatically generate professional architecture documentation.
use crate::generator::context::GeneratorContext;
use anyhow::Result;
use std::path::Path;
use std::process::Stdio;
use tokio::process::Command as TokioCommand;

/// Mermaid diagram fixer
/// 
/// Uses the mermaid-fixer program to fix syntax errors in mermaid diagrams generated by LLMs
pub struct MermaidFixer;

impl MermaidFixer {
    /// Check if mermaid-fixer is available
    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,
        }
    }

    /// Fix mermaid charts in specified directory
    /// 
    /// # Arguments
    /// - `context`: Generator context containing configuration information
    /// - `target_dir`: Directory path to fix
    /// 
    /// # Returns
    /// - `Ok(())`: Fix succeeded or skipped
    /// - `Err(anyhow::Error)`: Error occurred during fixing process
    pub async fn fix_mermaid_charts(
        context: &GeneratorContext,
        target_dir: &Path,
    ) -> Result<()> {
        // Check if mermaid-fixer is available
        if !Self::is_available().await {
            let msg = context.config.target_language.msg_mermaid_not_installed();
            println!("{}", msg);
            println!("💡 Tip: Run 'cargo install mermaid-fixer' to install the mermaid fixing tool");
            return Ok(());
        }

        println!("🔧 Starting mermaid chart fixing...");

        // Build mermaid-fixer command
        let mut cmd = TokioCommand::new("mermaid-fixer");
        
        // Set target directory
        cmd.arg("--directory").arg(target_dir);
        
        // Get LLM parameters from configuration
        let llm_config = &context.config.llm;
        
        // Set model parameters
        cmd.arg("--llm-model").arg(&llm_config.model_powerful);
        
        // Set API key
        if !llm_config.api_key.is_empty() {
            cmd.arg("--llm-api-key").arg(&llm_config.api_key);
        }
        
        // Set API base URL
        if !llm_config.api_base_url.is_empty() {
            cmd.arg("--llm-base-url").arg(&llm_config.api_base_url);
        }
        
        // Enable verbose output
        cmd.arg("--verbose");
        
        // Set stdout and stderr to inherit so we can see output in main program
        cmd.stdout(Stdio::inherit());
        cmd.stderr(Stdio::inherit());

        println!("🚀 Executing command (showing partial info): mermaid-fixer --directory {} --llm-model {} --verbose", 
                 target_dir.display(), 
                 llm_config.model_powerful);

        // Execute command
        match cmd.status().await {
            Ok(status) => {
                if status.success() {
                    println!("✅ Mermaid chart fixing completed");
                } else {
                    println!("⚠️ mermaid-fixer execution completed but returned non-zero status code: {}", 
                             status.code().unwrap_or(-1));
                    println!("💡 This may indicate some charts cannot be fixed, but won't affect subsequent processes");
                }
            }
            Err(e) => {
                let msg = context.config.target_language.msg_mermaid_error();
                println!("{}", msg.replace("{}", &e.to_string()));
                println!("💡 Mermaid chart fixing failed, but won't block subsequent processes");
            }
        }

        Ok(())
    }

    /// Automatically fix mermaid charts after document output
    /// 
    /// This is a convenience method that automatically uses the output directory as the fixing target
    pub async fn auto_fix_after_output(context: &GeneratorContext) -> Result<()> {
        let output_dir = &context.config.output_path;
        
        if !output_dir.exists() {
            println!("⚠️ Output directory does not exist, skipping mermaid chart fixing");
            return Ok(());
        }

        Self::fix_mermaid_charts(context, output_dir).await
    }
}