Advanced Usage

Custom Draw Targets

DrawTarget::to_writer accepts any Write + Send + 'static. This is useful for tests, logs, or embedding progress output into a larger terminal abstraction.

#![allow(unused)]
fn main() {
let target = loaders::DrawTarget::to_writer(Vec::<u8>::new());
let pb = loaders::ProgressBar::with_draw_target(10, target);
pb.inc(1);
}

CI, Pipes, and NO_COLOR

Terminal detection checks common CI variables and stream capabilities. Non-TTY targets use newline snapshots instead of cursor movement. The NO_COLOR environment variable disables ANSI color output everywhere the crate emits color.

On Windows consoles, interactive targets enable virtual terminal mode so progress bars and spinners update on the same line when the terminal supports ANSI cursor controls.

Platform Coverage

loaders is dependency-free and uses std + platform APIs for terminal detection:

  • Windows consoles use Win32 handles, console mode checks, and console width/height queries.
  • Unix-family terminals (Linux, macOS, BSD, and similar) use isatty and ioctl.

The crate supports both 32-bit and 64-bit targets as long as Rust supports the target.

Hidden Bars in Tests

#![allow(unused)]
fn main() {
let pb = loaders::ProgressBar::hidden();
pb.inc(1);
assert_eq!(pb.position(), 1);
}

Custom Template Keys

Custom keys let applications render domain terms without forking the renderer.

#![allow(unused)]
fn main() {
let style = loaders::ProgressStyle::with_template("{phase} {bar}")?
    .with_key("phase", |state| format!("phase {}", state.pos / 10 + 1));
Ok::<(), loaders::bar::template::TemplateError>(())
}

Thread Safety Model

ProgressBar is a cloneable handle around shared state. Clone it into worker threads and call inc, set_message, or finish from those threads. Each method locks briefly around state changes and rendering.

Draw Rate Limiting

For high-throughput loops, set draw_delta to redraw every N items and draw_rate to cap terminal writes per second.

#![allow(unused)]
fn main() {
let pb = loaders::ProgressBar::builder()
    .length(1_000_000)
    .draw_delta(1_000)
    .draw_rate(20)
    .build();
}

Capturing Output

Use a custom writer when assertions need rendered text. Use ProgressBar::hidden() when the test only needs state.