Async-first terminal UI spinners and progress bars
Something went wrong. Try again.
Rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134//! strides is an async-first crate to support building command line tools which display progress to//! the user. The purpose is similar to that of the widely used indicatif crate but focuses on//! integrating with async futures and streams and drive progress animations based on polling//! state.//!//! Instead of integrating progress bar and spinner UI elements along an asynchronous program,//! strides provides utilities to integrate these elements as part of the [`Future`] and//! [`Stream`](futures_lite::Stream) abstractions.//!//! ## Spinners//!//! A spinner is a UI element that represents ongoing work. It is usually iconified as a circular//! motion but anything that streams Unicode characters can be used. To create a spinner, import//! the [`Spinner`](crate::spinner::Spinner) struct and pass it a string slice://!//! ```rust//! let abc = strides::spinner::Spinner::new("abc");//! ```//!//! The [`ticks()`](crate::spinner::Spinner::ticks) method returns an infinite stream that cycles//! through the characters of the string slice. The rate at which characters are cycled is set to//! every 80ms and can be changed with the//! [`with_interval()`](crate::spinner::Spinner::with_interval) function.//!//! The [`spinner::styles`] module provides a few pre-defined spinner//! styles.//!//! ## Bars//!//! A [`Bar`](crate::bar::Bar) renders fractional progress as a strip of characters. It is//! defined by two characters, one for the empty portion and one for the filled portion. Create//! one with [`Bar::new()`](crate::bar::Bar::new) or pick a pre-defined variant from//! [`bar::styles`]://!//! ```rust//! let bar = strides::bar::styles::THIN_LINE//! .with_border("[", "]")//! .with_filled_style(owo_colors::Style::new().bright_purple());//! ```//!//! Borders, an optional in-between separator, and per-portion colors are configured via the//! builder methods on [`Bar`](crate::bar::Bar). The bar is attached to a [`Theme`] with//! [`with_bar()`](crate::Theme::with_bar); width defaults to the terminal size and can be//! overridden with [`with_bar_width()`](crate::Theme::with_bar_width).//!//! ## Themes//!//! A [`Theme`] bundles a [`Spinner`](crate::spinner::Spinner) and a [`Bar`](crate::bar::Bar)//! into a single configuration object that can be passed to both the futures and streams//! progress APIs://!//! ```rust//! let theme = strides::Theme::new()//! .with_bar(strides::bar::styles::PARALLELOGRAM)//! .with_spinner(strides::spinner::styles::DOTS_3);//! ```//!//! A bare [`Spinner`](crate::spinner::Spinner) can also be passed directly wherever a//! [`Theme`] is expected.//!//! ## Futures//!//! Import the [`FutureExt`](crate::future::FutureExt) extension trait and call//! [`progress()`](crate::future::FutureExt::progress) on any [`Future`] to obtain a//! [`ProgressBuilder`](crate::future::ProgressBuilder). Capabilities compose freely://! [`with_message`](crate::future::ProgressBuilder::with_message) sets a static message,//! [`with_messages`](crate::future::ProgressBuilder::with_messages) installs a//! [`Stream`](futures_lite::Stream) whose values replace the displayed message as they arrive,//! and [`with_fraction`](crate::future::ProgressBuilder::with_fraction) drives the progress bar//! from a `Stream<Item = f64>`.//!//! ```rust,no_run//! use strides::future::FutureExt;//! use strides::spinner::styles::DOTS_3;//! use std::time::Duration;//!//! # futures_lite::future::block_on(async {//! std::pin::pin!(async {//! // Simulate work by waiting for three seconds.//! futures_timer::Delay::new(Duration::from_secs(3)).await;//! })//! .progress(DOTS_3)//! .with_message("this will take some time")//! .await;//! # });//! ```//!//! For multiple concurrent futures use [`future::Group`], which renders one line per task//! with optional per-task progress bars and dynamic messages.//!//! ## Streams//!//! Import the [`StreamExt`](crate::stream::StreamExt) extension trait and call//! [`progress()`](crate::stream::StreamExt::progress) with a fraction closure. The closure//! receives the monotonically increasing item number (starting at 1) and a reference to the//! item, so the fraction can be derived from a known total or from the item itself (e.g.//! accumulated bytes / `Content-Length`). The returned//! [`StreamProgressBuilder`](crate::stream::StreamProgressBuilder) accepts a//! [`with_messages`](crate::stream::StreamProgressBuilder::with_messages) stream for//! dynamic text.//!//! ```rust,no_run//! use futures_lite::{StreamExt as _, stream};//! use strides::stream::StreamExt;//! use strides::Theme;//! use strides::{bar, spinner};//!//! let theme = Theme::new()//! .with_spinner(spinner::styles::DOTS_3)//! .with_bar(bar::styles::SHADED);//!//! # futures_lite::future::block_on(async {//! let total = 100;//! stream::iter(0..total)//! .progress(theme, move |i, _| i as f64 / total as f64)//! .for_each(|_| {})//! .await;//! # });//! ```//!//! ## Output//!//! strides currently renders all progress output to `stdout`. A renderer abstraction (for//! tests or TUI embedding) is intentionally out of scope for 1.0 in favor of simplicity.
pub mod bar;pub mod future;pub mod spinner;pub mod stream;pub mod term;pub mod theme;
pub use theme::Theme;