progress-token 0.1.0

A library for tracking progress of long-running tasks
Documentation

progress-token

A Rust library for hierarchical progress tracking with support for cancellation, status updates, and nested operations.

Crates.io Documentation License: MIT

Features

  • 🌳 Hierarchical Progress: Create trees of operations with weighted progress tracking
  • 📢 Status Updates: Track and propagate status messages through the operation hierarchy
  • ⏸️ Cancellation: Built-in support for cancelling operations and their children
  • 📊 Progress States: Support for both determinate (0.0-1.0) and indeterminate progress
  • 🔄 Multiple Subscribers: Allow multiple parts of your application to monitor progress
  • 🧮 Automatic Aggregation: Progress automatically calculated from weighted child tasks

Installation

Add this to your Cargo.toml:

[dependencies]
progress-token = "0.1.0"

Quick Start

use progress_token::ProgressToken;

#[tokio::main]
async fn main() {
    // Create a root progress token
    let root = ProgressToken::new("Main task");
    
    // Create child tasks with weights
    let process = ProgressToken::child(&root, 0.7, "Processing"); // 70% of total
    let cleanup = ProgressToken::child(&root, 0.3, "Cleanup");    // 30% of total
    
    // Subscribe to progress updates
    let mut updates = root.subscribe();
    
    // Update progress as work is done
    process.progress(0.5);  // Root progress becomes 0.35 (0.5 * 0.7)
    process.status("Processing file 1/10");
    
    cleanup.progress(1.0);  // Root progress becomes 0.65 (0.35 + 1.0 * 0.3)
    cleanup.status("Cleanup complete");
}

Usage Examples

Basic Progress Tracking

let token = ProgressToken::new("Processing files");

// Update progress
token.progress(0.25);
token.status("Processing file 1/4");

// Mark as complete when done
token.complete();

Status Updates

Status messages propagate through the hierarchy, with the most specific (deepest) status being reported:

let root = ProgressToken::new("Backup");
let compress = ProgressToken::child(&root, 1.0, "Compressing files");

// Update status with more specific information
compress.status("Compressing images/photo1.jpg");

// Get full status hierarchy
let statuses = root.statuses();
assert_eq!(statuses, vec![
    "Backup",
    "Compressing files", 
    "Compressing images/photo1.jpg"
]);

Progress Subscription

let token = ProgressToken::new("Long operation");
let mut updates = token.subscribe();

tokio::spawn(async move {
    while let Some(update) = updates.next().await {
        println!(
            "Progress: {:?}, Current status: {}", 
            update.progress,
            update.status()
        );
    }
});

Cancellation

let token = ProgressToken::new("Cancellable operation");

// In one part of your code
if error_condition {
    token.cancel(); // Cancels this token and all children
}

// In another part
if token.is_cancelled() {
    return;
}

Implementation Notes

  • Progress values are automatically clamped to the range 0.0-1.0
  • Child task weights should sum to 1.0 for accurate progress calculation
  • Status updates and progress changes are broadcast to all subscribers
  • Completed or cancelled tokens ignore further progress/status updates
  • The broadcast channel has a reasonable buffer size to prevent lagging

License

This project is licensed under the MIT License - see the LICENSE.md file for details.