errcraft 0.1.0

Beautiful, structured, and colorful error handling for Rust.
Documentation
//! Example demonstrating errcraft in async contexts.
//!
//! Note: This example requires tokio to be added as a dev-dependency.
//! Run with: cargo run --example async_api

use errcraft::{craft, ErrFrame};
use std::time::Duration;

async fn fetch_user_data(user_id: u64) -> Result<String, ErrFrame> {
    // Simulate async operation
    tokio::time::sleep(Duration::from_millis(100)).await;

    // Simulate an error
    Err(craft!("Failed to fetch user data")
        .context("user_id", user_id)
        .context("service", "user-api")
        .context_text("Remote service returned 404"))
}

async fn get_user_profile(user_id: u64) -> Result<String, ErrFrame> {
    fetch_user_data(user_id).await.map_err(|e| {
        craft!("Profile retrieval failed")
            .context("user_id", user_id)
            .with_source(e)
    })
}

async fn sync_user_data(user_id: u64) -> Result<(), ErrFrame> {
    get_user_profile(user_id).await.map_err(|e| {
        craft!("User data synchronization failed")
            .context("operation", "sync")
            .context("timestamp", chrono::Utc::now().to_rfc3339())
            .with_source(e)
    })?;

    Ok(())
}

#[tokio::main]
async fn main() {
    println!("=== errcraft Async API Example ===\n");

    // Example 1: Simple async error
    println!("Example 1: Async fetch error");
    if let Err(e) = fetch_user_data(42).await {
        e.eprint();
    }
    println!("\n{}\n", "=".repeat(60));

    // Example 2: Nested async errors
    println!("Example 2: Nested async error chain");
    if let Err(e) = sync_user_data(123).await {
        e.eprint();
    }
    println!("\n{}\n", "=".repeat(60));

    // Example 3: Multiple concurrent errors
    println!("Example 3: Concurrent operations");
    let tasks = vec![
        tokio::spawn(fetch_user_data(1)),
        tokio::spawn(fetch_user_data(2)),
        tokio::spawn(fetch_user_data(3)),
    ];

    for (i, task) in tasks.into_iter().enumerate() {
        match task.await {
            Ok(Ok(_)) => println!("Task {} succeeded", i + 1),
            Ok(Err(e)) => {
                println!("Task {} failed:", i + 1);
                e.eprint();
                println!();
            }
            Err(e) => println!("Task {} panicked: {}", i + 1, e),
        }
    }
}