Expand description
A modern, async-first progress tracking library for Rust.
This crate provides types and utilities for tracking progress of long-running operations
in an async context. It uses Rust’s Stream
API to emit progress updates with support for
different states (working, paused, completed, cancelled).
§Features
- Async-first: Built around Rust’s async/await and Stream APIs
- Zero-allocation progress updates: Efficient progress reporting
- Flexible progress tracking: Support for current/total, messages, and cancellation
- Type-safe: Full Rust type safety with meaningful error messages
- Lightweight: Minimal dependencies and fast compilation
- Convenient observing: Extension methods for easy progress monitoring
§Examples
§Using the observe extension (recommended)
The ProgressExt::observe
method provides a convenient way to monitor progress
without manually managing streams and select macros:
use progressor::{progress, ProgressExt};
let result = progress(100, |mut updater| async move {
for i in 0..=100 {
// Update progress
updater.update(i);
// Add messages for important milestones
if i % 25 == 0 {
updater.update_with_message(i, format!("Milestone: {}%", i));
}
}
"Task completed!"
})
.observe(|update| {
println!("Progress: {}%", (update.completed_fraction() * 100.0) as u32);
if let Some(message) = update.message() {
println!(" {}", message);
}
})
.await;
println!("Result: {}", result);
§Manual stream monitoring with tokio::select!
For more control, you can manually monitor the progress stream:
use progressor::{progress, Progress};
use futures_util::StreamExt;
let task = progress(100, |mut updater| async move {
for i in 0..=100 {
// Update progress
updater.update(i);
// Add messages for important milestones
if i % 25 == 0 {
updater.update_with_message(i, format!("Milestone: {}%", i));
}
}
"Task completed!"
});
// Monitor progress concurrently
let mut progress_stream = task.progress();
tokio::select! {
result = task => {
println!("Result: {}", result);
}
_ = async {
while let Some(update) = progress_stream.next().await {
println!("Progress: {}%", (update.completed_fraction() * 100.0) as u32);
if let Some(message) = update.message() {
println!(" {}", message);
}
}
} => {}
}
§Advanced usage with state handling
Monitor different progress states and handle pause/cancel operations:
use progressor::{progress, ProgressExt, State};
let result = progress(100, |mut updater| async move {
for i in 0..=100 {
// Update progress
updater.update(i);
// Pause at 50%
if i == 50 {
updater.pause();
// Simulate some async work during pause
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
}
}
"Task completed!"
})
.observe(|update| {
match update.state() {
State::Working => println!("Working: {}%", (update.completed_fraction() * 100.0) as u32),
State::Paused => println!("Paused at {}%", (update.completed_fraction() * 100.0) as u32),
State::Completed => println!("Completed!"),
State::Cancelled => println!("Cancelled!"),
}
})
.await;
println!("Result: {}", result);
Structs§
- Progress
Update - Represents a single progress update with current status, total, and optional metadata.
- Progress
Updater std
- A handle for updating progress during execution of a future.
Enums§
- State
- Represents the state of a progress-tracked operation.
Traits§
- Progress
- A trait for futures that can report progress updates.
- Progress
Ext - Extension trait providing convenient methods for observing progress updates.
Functions§
- progress
std
- Creates a progress-tracked future from a closure.