forge-guard 0.1.2

Pre-deployment smart contract auditing framework for Foundry
Documentation
//! `forge benchmark` — run performance benchmarks.

use crate::benchmark::BenchmarkRunner;

use super::BenchmarkArgs;
use anyhow::Result;
use colored::*;

/// Run performance benchmarks for the audit framework.
pub fn run(args: &BenchmarkArgs) -> Result<()> {
    eprintln!("{}", "⚡ Forge Guard — Benchmark".bold());
    eprintln!("   Iterations: {}", args.iterations);
    eprintln!("   Warmup:     {}", args.warmup);

    let mut runner = BenchmarkRunner::new(args.iterations, args.warmup);

    // Run benchmarks for each module
    let results = match &args.module {
        Some(module) => vec![runner.benchmark_module(module)?],
        None => runner.benchmark_all()?,
    };

    // Display results
    println!(
        "\n{}",
        "═══════════════════════════════════════".bright_blue()
    );
    println!(
        "{}",
        "         BENCHMARK RESULTS              "
            .bright_blue()
            .bold()
    );
    println!(
        "{}",
        "═══════════════════════════════════════".bright_blue()
    );

    for result in &results {
        println!("\n  📊 {}:", result.name.bold());
        println!("     Avg:     {:.2}ms", result.avg_ms);
        println!("     Min:     {:.2}ms", result.min_ms);
        println!("     Max:     {:.2}ms", result.max_ms);
        println!("     Median:  {:.2}ms", result.median_ms);
        println!("     P99:     {:.2}ms", result.p99_ms);
        println!("     Samples: {}", result.samples);
    }

    // Save results if requested
    if let Some(save_path) = &args.save {
        let json = serde_json::to_string_pretty(&results)?;
        std::fs::write(save_path, json)?;
        println!(
            "\n{} Results saved to {}",
            "💾".green(),
            save_path.display()
        );
    }

    // Compare with baseline
    if let Some(baseline_path) = &args.compare {
        let baseline_content = std::fs::read_to_string(baseline_path)?;
        let baseline: Vec<crate::benchmark::BenchmarkResult> =
            serde_json::from_str(&baseline_content)?;
        println!("\n{}", "── Comparison with Baseline ──".bold());
        for result in &results {
            if let Some(baseline) = baseline.iter().find(|b| b.name == result.name) {
                let diff = result.avg_ms - baseline.avg_ms;
                let pct = (diff / baseline.avg_ms) * 100.0;
                if diff > 0.0 {
                    println!(
                        "  {} {}: +{:.1}ms ({:+.1}%)",
                        "🔴".red(),
                        result.name,
                        diff,
                        pct
                    );
                } else {
                    println!(
                        "  {} {}: {:.1}ms ({:+.1}%)",
                        "🟢".green(),
                        result.name,
                        diff,
                        pct
                    );
                }
            }
        }
    }

    Ok(())
}