use async_inspect::prelude::*;
use colored::Colorize;
use std::time::Duration;
use tokio::time::sleep;
#[async_inspect::trace]
async fn fetch_user_profile(user_id: u32) -> String {
println!(" 📥 Fetching profile for user {}...", user_id);
sleep(Duration::from_millis(80)).await;
let profile = format!("Profile(id={})", user_id);
println!(" ✓ Profile fetched: {}", profile);
profile
}
#[async_inspect::trace]
async fn fetch_user_posts(user_id: u32) -> Vec<String> {
println!(" 📥 Fetching posts for user {}...", user_id);
sleep(Duration::from_millis(120)).await;
let posts = vec![
format!("Post 1 by user {}", user_id),
format!("Post 2 by user {}", user_id),
];
println!(" ✓ Posts fetched: {} items", posts.len());
posts
}
#[async_inspect::trace]
async fn process_user_data(user_id: u32) -> (String, Vec<String>) {
println!("⚙️ Processing user {}...", user_id);
let profile = fetch_user_profile(user_id).await;
let posts = fetch_user_posts(user_id).await;
println!("✓ Processing complete for user {}", user_id);
(profile, posts)
}
#[async_inspect::trace]
async fn aggregate_user_data(user_ids: Vec<u32>) -> Vec<(String, Vec<String>)> {
println!("📊 Aggregating data for {} users...", user_ids.len());
let mut results = Vec::new();
for user_id in user_ids {
let user_data = process_user_data(user_id).await;
results.push(user_data);
}
println!("✓ Aggregation complete");
results
}
#[async_inspect::trace]
async fn complex_pipeline() -> std::result::Result<String, String> {
println!("🚀 Starting complex pipeline...");
let data = fetch_user_profile(1).await;
sleep(Duration::from_millis(50)).await;
let transformed = format!("Transformed({})", data);
sleep(Duration::from_millis(40)).await;
println!("✓ Pipeline complete");
Ok(transformed)
}
#[tokio::main]
async fn main() {
println!("╔════════════════════════════════════════════════════════════╗");
println!(
"║ {} - Proc Macro Test Example ║",
"[async-inspect]".on_purple().white().bold()
);
println!("╚════════════════════════════════════════════════════════════╝\n");
println!(
"{}\n",
"[*] This example tests the #[async_inspect::trace] macro"
.on_yellow()
.white()
.bold()
);
println!(" All async functions are automatically instrumented!");
println!(" Every .await point is labeled and tracked.\n");
println!("═══ Scenario 1: Simple Function ═══");
let _ = fetch_user_profile(42).await;
sleep(Duration::from_millis(50)).await;
println!("\n═══ Scenario 2: Multiple Awaits ═══");
let _ = process_user_data(123).await;
sleep(Duration::from_millis(50)).await;
println!("\n═══ Scenario 3: Complex Workflow ═══");
let _ = aggregate_user_data(vec![1, 2, 3]).await;
sleep(Duration::from_millis(50)).await;
println!("\n═══ Scenario 4: Pipeline ═══");
match complex_pipeline().await {
Ok(result) => println!("✓ Result: {}", result),
Err(e) => println!("❌ Error: {}", e),
}
sleep(Duration::from_millis(100)).await;
println!("\n✅ All scenarios complete!\n");
let reporter = Reporter::global();
println!("┌────────────────────────────────────────────────────────────┐");
println!("│ Summary Report │");
println!("└────────────────────────────────────────────────────────────┘");
reporter.print_summary();
println!("\n┌────────────────────────────────────────────────────────────┐");
println!("│ Gantt Timeline │");
println!("└────────────────────────────────────────────────────────────┘");
reporter.print_gantt_timeline();
println!("\n┌────────────────────────────────────────────────────────────┐");
println!("│ Generating HTML Report │");
println!("└────────────────────────────────────────────────────────────┘");
let html_reporter = HtmlReporter::global();
let html_path = "proc_macro_test_report.html";
match html_reporter.save_to_file(html_path) {
Ok(_) => {
println!("\n✅ HTML report saved to: {}", html_path);
println!("\n🌐 Look for these automatic instrumentations:");
println!(" • fetch_user_profile::await#1");
println!(" • fetch_user_posts::await#1");
println!(" • process_user_data::await#1 (fetch_user_profile)");
println!(" • process_user_data::await#2 (fetch_user_posts)");
println!(" • aggregate_user_data::await#1 (process_user_data loop)");
println!(" • complex_pipeline::await#1, #2, #3");
println!(
"\n Open: file://{}/{}",
std::env::current_dir().unwrap().display(),
html_path
);
}
Err(e) => {
println!("\n❌ Failed to save HTML report: {}", e);
}
}
let stats = Inspector::global().stats();
println!("\n╔════════════════════════════════════════════════════════════╗");
println!("║ Proc Macro Test Results ║");
println!("╚════════════════════════════════════════════════════════════╝");
println!("\n📊 Total tasks: {}", stats.total_tasks);
println!("✅ Completed: {}", stats.completed_tasks);
println!("📋 Total events: {}", stats.total_events);
println!(
"⏱️ Duration: {:.2}s",
stats.timeline_duration.as_secs_f64()
);
println!("\n💡 The proc macro automatically:");
println!(" ✓ Registers each function as a tracked task");
println!(" ✓ Labels every .await point (await#1, await#2, etc.)");
println!(" ✓ Tracks execution time for each await");
println!(" ✓ Records completion or failure");
println!("\n No manual instrumentation needed!");
println!();
}