loaders 0.0.0

A fully-featured, customisable progress bar and loading indicator library for Rust CLI and terminal applications
Documentation
  • Coverage
  • 96.36%
    318 out of 330 items documented170 out of 191 items with examples
  • Size
  • Source code size: 230.63 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 3.61 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • muhammad-fiaz/loaders
    1 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • muhammad-fiaz

loaders is a production-minded, dependency-free terminal progress library for Rust. It provides progress bars, spinners, multi-progress rendering, iterator adapters, terminal capability detection, themes, templates, ANSI styling, and test-friendly draw targets using only the Rust standard library.

If you love loaders, make sure to give it a star ⭐.



Feature Description Documentation
Zero Dependencies Built entirely with std, with no third-party runtime or feature dependencies. Docs
Progress Bars Known-length bars with position, total, percentage, ETA, elapsed time, and rate. Docs
Spinners Indeterminate loading indicators with manual ticks or background steady ticks. Docs
27 Spinner Presets Dots, line, pipe, star, meter, pulse, blocks, arrows, clock, weather, and more. Docs
MultiProgress Render multiple bars in a stable shared terminal block for concurrent jobs. Docs
Iterator Wrapping Add .progress(), .progress_count(), and custom-style adapters to iterators. Docs
Template Engine Parse {bar}, {percent}, {bytes_per_sec}, {eta}, and custom keys once. Docs
Status Templates Render {status}, {remaining}, {human_remaining}, {ratio}, and {rate}. Docs
Custom Template Keys Register closures for app-specific template variables. Docs
Reusable Bar Characters Define custom fill, head, and empty characters with ProgressChars. Docs
Themes Default, Unicode, Braille, Block, Minimal, Colorful, Gradient, Retro, and more. Docs
ANSI Colors 16-color, 256-color, and RGB ANSI generation with text attributes. Docs
NO_COLOR Compliance Suppresses ANSI styling when NO_COLOR is set. Docs
CI-Aware Output Detects common CI environments and avoids unreadable terminal control output. Docs
Custom Draw Targets Write to stdout, stderr, hidden targets, or any Write + Send target. Docs
Thread Safety Clone progress handles across worker threads using shared synchronized state. Docs
Draw Throttling Limit redraws by position delta and maximum redraws per second. Docs
Outcome Helpers Stop spinners with success, failure, warning, or info markers. Docs

Prerequisites

Requirement Version Notes
Rust Stable with Edition 2024 support The crate uses Rust 2024 edition metadata.
Dependencies None Only the Rust standard library is used.
Terminal Optional Hidden and custom writer targets work without a TTY.

Supported Platforms

Platform Architectures Status
Windows x86_64, aarch64, x86 Interactive same-line redraw, Win32 terminal size detection, newline fallback for non-TTY.
Linux x86_64, aarch64, riscv64 Full terminal width and TTY detection support.
macOS x86_64, aarch64 (Apple Silicon) Full terminal width and TTY detection support.
Other Unix target-dependent Uses the same isatty + ioctl detection path where available.

Installation

Method 1: Cargo Add (Recommended)

Add loaders to your Cargo project dynamically:

cargo add loaders

Method 2: Manual Cargo.toml Configuration

Add this directly to your Cargo.toml dependencies block:

[dependencies]
loaders = "0.0.0"

Quick Start

use loaders::ProgressBar;
use std::thread;
use std::time::Duration;

fn main() {
    let pb = ProgressBar::new(100);

    for _ in 0..100 {
        pb.inc(1);
        thread::sleep(Duration::from_millis(10));
    }

    pb.finish_with_message("done");
}

Usage Examples

Basic Progress Bar

use loaders::{ProgressBar, Theme};

let pb = ProgressBar::new(100);
pb.set_prefix("build");
pb.set_style(Theme::Unicode.style());
pb.inc(25);
pb.finish_with_message("complete");

Spinner Quick Start

use loaders::{Spinner, spinner::frames::DOTS};

let spinner = Spinner::with_message(&DOTS, "connecting");
spinner.tick();
spinner.stop_with_symbol("", "connected");

Iterator Integration

use loaders::ProgressIterator;

let sum: u64 = (0..100u64).progress().sum();
println!("{sum}");

MultiProgress with Threads

use loaders::{MultiProgress, ProgressBar};
use std::thread;

fn main() {
    let multi = MultiProgress::new();
    let first = multi.add(ProgressBar::new(50));
    let second = multi.add(ProgressBar::new(75));

    let a = thread::spawn(move || {
        for _ in 0..50 {
            first.inc(1);
        }
        first.finish_with_message("first done");
    });

    let b = thread::spawn(move || {
        for _ in 0..75 {
            second.inc(1);
        }
        second.finish_with_message("second done");
    });

    multi.join();
    let _ = a.join();
    let _ = b.join();
}

Custom Styling

use loaders::{Color, ColorSpec, ProgressBar, ProgressChars, ProgressStyle};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let style = ProgressStyle::with_template(
        "{prefix} [{bar:40.#/-}] {pos}/{len} ({percent:.1}%) {msg}",
    )?
    .progress_chars_set(ProgressChars::equals())
    .color(ColorSpec::new().set_fg(Color::Cyan).set_bold(true));

    let pb = ProgressBar::new(100);
    pb.set_style(style);
    pb.set_prefix("custom");
    pb.inc(40);
    pb.finish_with_message("done");
    Ok(())
}

Advanced Progress State & Status Templates

use loaders::{ProgressBar, ProgressStyle};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let style = ProgressStyle::with_template(
        "{prefix} [{bar:20}] {percent:.1}% | {human_remaining} left | {status}",
    )?;

    let pb = ProgressBar::with_style(100, style);
    pb.set_prefix("task");
    pb.inc(40);
    assert_eq!(pb.remaining(), Some(60));
    pb.finish_with_symbol("ok", "complete");
    Ok(())
}

Download-Style Byte Progress

use loaders::{ProgressBar, ProgressStyle};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let style = ProgressStyle::with_template(
        "{prefix} [{bar:30}] {bytes}/{total_bytes} {bytes_per_sec} ETA {eta}",
    )?;

    let pb = ProgressBar::builder()
        .length(50 * 1024 * 1024)
        .style(style)
        .prefix("download")
        .build();

    pb.inc(1024 * 1024);
    pb.finish_with_message("saved");
    Ok(())
}

Custom Template Keys

use loaders::{ProgressBar, ProgressStyle};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let style = ProgressStyle::with_template("{phase} [{bar:20}] {msg}")?
        .with_key("phase", |state| format!("phase {}", state.pos / 10 + 1));

    let pb = ProgressBar::builder().length(30).style(style).build();
    pb.inc(10);
    pb.finish_with_message("done");
    Ok(())
}

Template Variable Reference

Variable Format Spec Description Example Output
{bar} :40, :40.#/- Progress bar segment. ########>-------
{wide_bar} none Progress bar sized to remaining template width. ############>...
{pos} none Current position. 42
{count} none Compact current position. 1.2k
{human_pos} none Compact current position alias. 1.2k
{len} none Total length or ? when unknown. 100
{total_count} none Compact total length. 1.5M
{human_len} none Compact total length alias. 1.5M
{remaining} none Remaining units. 58
{human_remaining} none Compact remaining units. 58.0k
{ratio} :.3 Completion ratio. 0.420
{percent} :.2 Percentage without a percent sign. 42 or 42.50
{elapsed} none Human elapsed time. 3m 14s
{elapsed_precise} none Precise elapsed time. 00:03:14
{elapsed_millis} none Millisecond elapsed time. 00:03:14.123
{eta} none Estimated remaining time. ~12s
{eta_precise} none Precise ETA. 00:00:12
{eta_millis} none Millisecond ETA. 00:00:12.345
{per_sec} :.2 Average units per second. 120.50
{rate} none Formatted item rate. 1.23k items/s
{bytes} none Current position as bytes. 1.00 MB
{total_bytes} none Total length as bytes. 50.00 MB
{bytes_per_sec} none Byte throughput. 1.23 MB/s
{spinner} none Current spinner frame.
{msg} :20, :>20, :^20 Message text with optional padding/truncation. downloading
{prefix} :10, :>10, :^10 Prefix text with optional padding/truncation. task
{postfix} :10, :>10, :^10 Postfix text with optional padding/truncation. ok
{status} :10, :>10, :^10 Running, spinning, finished, or abandoned state. running
{wide_msg} none, :20, :>20, :^20 Message padded or truncated to terminal or explicit width. terminal-width text

Text width specs use < (left), > (right), and ^ (center) alignment with fixed width.


Theme Gallery

Approximate 60% previews:

default   [##################>-----------]
unicode   [━━━━━━━━━━━━━━━━━━╸░░░░░░░░░░░]
braille   [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣦]
block     [██████████████████▉▒▒▒▒▒▒▒▒▒▒▒]
minimal   ==================>...........
colorful  [##################>-----------]
gradient  [██████████████████▓░░░░░░░░░░░]
retro     [==================>-----------]
dots      [••••••••••••••••••∘           ]
rounded   [●●●●●●●●●●●●●●●●●●○───────────]
shaded    [▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▫           ]
arrows    [>>>>>>>>>>>>>>>>>>------------]

Spinner Presets

Preset Sample Frames
dots ⠋ ⠙ ⠹
dots2 ⣾ ⣽ ⣻
dots3 ⠋ ⠙ ⠚
line `- \
pipe ┤ ┘ ┴
star ✶ ✸ ✹
bounce ⠁ ⠂ ⠄
arrows ← ↖ ↑
clock 🕛 🕐 🕑
earth 🌍 🌎 🌏
moon 🌑 🌒 🌓
runner 🚶 🏃 🚶
pong ▐⠂ ▐ ⠂ ▐ ⠂
shark `▐
weather ☀️ ⛅ 🌤
christmas 🌲 🎄 🌲
toggle ■ □ ■
square_corners ◰ ◳ ◲
binary 0 1 10
meter ▱▱▱ ▰▱▱ ▰▰▱
quadrants ◐ ◓ ◑
triangles ◢ ◣ ◤
circle ○ ◔ ◐
box_bounce moving block
pulse . .. ...
heart ♡ ♥ ♡
progress_blocks ▁ ▂ ▃

Configuration

use loaders::{DrawTarget, ProgressBar, Theme};

let pb = ProgressBar::builder()
    .length(1_000)
    .style(Theme::Block.style())
    .target(DrawTarget::stderr())
    .draw_delta(10)
    .draw_rate(20)
    .prefix("build")
    .message("compiling")
    .build();

Building & Testing

# Keep dependencies current in the lockfile
cargo update

# Check formatting
cargo fmt --all -- --check

# Run clippy across all targets
cargo clippy --all-targets -- -D warnings

# Run unit tests and doctests
cargo test --all

# Build every example
cargo build --examples

# Generate crate documentation
cargo doc --no-deps

Documentation

Online Documentation

Full guides and API walkthroughs are available at:

https://muhammad-fiaz.github.io/loaders

Generating Local Documentation

cargo doc --no-deps --open

Contributing

Contributions are welcome. Please keep the crate dependency-free, include focused tests for behavioral changes, and run the full verification commands from Building & Testing before opening a pull request.


License

MIT License - see LICENSE for details.



Links