### Basic Setup of IndicatifLayer in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Demonstrates the fundamental setup of the IndicatifLayer with tracing-subscriber. This involves creating an IndicatifLayer instance and integrating it into the subscriber's registry, ensuring progress bars are displayed correctly without interfering with logs. ```rust use tracing_indicatif::IndicatifLayer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; fn main() { let indicatif_layer = IndicatifLayer::new(); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); // Now any #[instrument] function will automatically show a progress bar } ``` -------------------------------- ### Customize Global Progress Bar Styles with ProgressStyle Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Demonstrates how to globally customize the progress bar appearance using `with_progress_style`. It utilizes special template keys like `{span_name}`, `{span_fields}`, and `{span_child_prefix}` for span-specific information and custom keys for conditional coloring. ```rust use std::time::Duration; use indicatif::{ProgressState, ProgressStyle}; use tracing::instrument; use tracing_indicatif::IndicatifLayer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; fn elapsed_subsec(state: &ProgressState, writer: &mut dyn std::fmt::Write) { let seconds = state.elapsed().as_secs(); let sub_seconds = (state.elapsed().as_millis() % 1000) / 100; let _ = writer.write_str(&format!("{}.{}s", seconds, sub_seconds)); } #[instrument] async fn build(unit: u64) { tokio::time::sleep(Duration::from_secs(2)).await; } #[tokio::main] async fn main() { let indicatif_layer = IndicatifLayer::new() .with_progress_style( ProgressStyle::with_template( "{color_start}{span_child_prefix}{span_fields} -- {span_name} {wide_msg} {elapsed_subsec}{color_end}" ) .unwrap() .with_key("elapsed_subsec", elapsed_subsec) .with_key("color_start", |state: &ProgressState, writer: &mut dyn std::fmt::Write| { let elapsed = state.elapsed(); if elapsed > Duration::from_secs(8) { let _ = write!(writer, "\x1b[31m"); // Red } else if elapsed > Duration::from_secs(4) { let _ = write!(writer, "\x1b[33m"); // Yellow } }) .with_key("color_end", |state: &ProgressState, writer: &mut dyn std::fmt::Write| { if state.elapsed() > Duration::from_secs(4) { let _ = write!(writer, "\x1b[0m"); } }), ) .with_span_child_prefix_symbol("↳ ") .with_span_child_prefix_indent(" "); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); build(42).await; } ``` -------------------------------- ### Progress Bars for Instrumented Async Functions in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Illustrates how to use the `#[instrument]` attribute with async functions to automatically generate progress bars. The progress bars appear when spans are entered and disappear upon completion, showcasing seamless integration with async runtimes like tokio. ```rust use std::time::Duration; use futures::stream::{self, StreamExt}; use rand::Rng; use tracing::{info, instrument}; use tracing_indicatif::IndicatifLayer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; #[instrument] async fn do_work(val: u64) -> u64 { let sleep_time = rand::rng().random_range(Duration::from_millis(250)..Duration::from_millis(500)); tokio::time::sleep(sleep_time).await; info!("doing work for val: {}", val); tokio::time::sleep(Duration::from_millis(500)).await; val + 1 } #[tokio::main] async fn main() { let indicatif_layer = IndicatifLayer::new(); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); // Process 20 items with 5 concurrent workers - each shows a progress bar let res: u64 = stream::iter((0..20).map(|val| do_work(val))) .buffer_unordered(5) .collect::>() .await .into_iter() .sum(); println!("final result: {}", res); } ``` -------------------------------- ### Per-Span Style Customization with IndicatifSpanExt Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Illustrates how to override the global progress bar style for individual spans using the `pb_set_style` method from the `IndicatifSpanExt` trait. This allows for distinct visual representations for different tasks within the application. ```rust use std::time::Duration; use indicatif::ProgressStyle; use tracing::{Span, instrument}; use tracing_indicatif::IndicatifLayer; use tracing_indicatif::span_ext::IndicatifSpanExt; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; #[instrument] async fn do_sub_work(val: u64) -> u64 { // Override style for this specific span - no spinner, just name and fields Span::current().pb_set_style( &ProgressStyle::with_template("{span_child_prefix}{span_name}{{{span_fields}}}").unwrap(), ); tokio::time::sleep(Duration::from_secs(3)).await; val + 1 } #[instrument] async fn do_work(mut val: u64) -> u64 { tokio::time::sleep(Duration::from_secs(1)).await; val = do_sub_work(val).await; val + 1 } #[tokio::main] async fn main() { let indicatif_layer = IndicatifLayer::new(); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); do_work(42).await; } ``` -------------------------------- ### Configure Max Progress Bars and Footer in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Configures the `IndicatifLayer` to limit the number of simultaneously displayed progress bars and provides a custom footer message to indicate the count of pending, non-visible bars. This is useful for managing screen real estate when many tasks might be running concurrently. Requires `indicatif` and `tracing-indicatif` crates. ```rust use indicatif::ProgressStyle; use tracing_indicatif::IndicatifLayer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; fn main() { let indicatif_layer = IndicatifLayer::new() .with_max_progress_bars( 5, // Maximum 5 visible progress bars Some(ProgressStyle::with_template("...and {pending_progress_bars} more not shown above.").unwrap()), ); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); } ``` -------------------------------- ### Filter Progress Bars with IndicatifFilter in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Demonstrates how to selectively enable or disable progress bars on a per-span basis using `IndicatifFilter`. This allows fine-grained control over which operations display progress indicators, preventing clutter for less critical tasks. It requires the `tracing` and `tracing-indicatif` crates. ```rust use std::time::Duration; use tracing::instrument; use tracing_indicatif::IndicatifLayer; use tracing_indicatif::filter::IndicatifFilter; use tracing_indicatif::filter::hide_indicatif_span_fields; use tracing_subscriber::fmt::format::DefaultFields; use tracing_subscriber::layer::Layer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; // This span WILL show a progress bar due to indicatif.pb_show field #[instrument(fields(indicatif.pb_show))] async fn do_visible_work(val: u64) -> u64 { tokio::time::sleep(Duration::from_millis(1500)).await; val + 1 } // This span will NOT show a progress bar (default is false) #[instrument] async fn do_hidden_work(mut val: u64) -> u64 { tokio::time::sleep(Duration::from_millis(500)).await; val = do_visible_work(val).await; val + 1 } #[tokio::main] async fn main() { // Use hide_indicatif_span_fields to remove pb_show/pb_hide from displayed fields let indicatif_layer = IndicatifLayer::new() .with_span_field_formatter(hide_indicatif_span_fields(DefaultFields::new())); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) // Apply filter: show_progress_bars_by_default = false .with(indicatif_layer.with_filter(IndicatifFilter::new(false))) .init(); do_hidden_work(42).await; } ``` -------------------------------- ### Configure Tick Settings for Progress Bars in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Customizes the `TickSettings` for `IndicatifLayer` to control the frequency of terminal redraws and the recalculation of progress bar states. This allows fine-tuning the visual responsiveness and performance of the progress bars. Requires `tracing-indicatif` crate. ```rust use std::time::Duration; use tracing_indicatif::{IndicatifLayer, TickSettings}; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; fn main() { let indicatif_layer = IndicatifLayer::new() .with_tick_settings(TickSettings { term_draw_hz: 30, // Redraw terminal 30 times per second default_tick_interval: Some(Duration::from_millis(50)), // Recalculate progress bar state every 50ms footer_tick_interval: None, // No automatic ticking for footer ..Default::default() }); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); } ``` -------------------------------- ### Safe Printing with indicatif_println/eprintln Macros in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Utilizes the `indicatif_println!` and `indicatif_eprintln!` macros to safely output messages to stdout and stderr without interfering with active progress bars. These macros ensure that console output is correctly interleaved with progress bar updates, preventing visual corruption. Requires `tracing` and `tracing-indicatif` crates. ```rust use std::time::Duration; use tracing::instrument; use tracing_indicatif::IndicatifLayer; use tracing_indicatif::{indicatif_println, indicatif_eprintln}; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; #[instrument] async fn do_work(val: u64) -> u64 { tokio::time::sleep(Duration::from_millis(500)).await; // These macros prevent output from being clobbered by progress bars indicatif_eprintln!("writing val {} to stderr", val); indicatif_println!("writing val {} to stdout", val); tokio::time::sleep(Duration::from_millis(500)).await; val + 1 } #[tokio::main] async fn main() { let indicatif_layer = IndicatifLayer::new(); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); do_work(42).await; } ``` -------------------------------- ### Controlling Progress Bars with IndicatifSpanExt in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt Shows how to use the `IndicatifSpanExt` trait to dynamically control individual progress bars. This includes setting length, position, style, and messages for spans, providing fine-grained control over progress bar appearance and behavior. ```rust use std::time::Duration; use futures::stream::{self, StreamExt}; use indicatif::ProgressStyle; use tracing::{Span, info_span, instrument}; use tracing_indicatif::IndicatifLayer; use tracing_indicatif::span_ext::IndicatifSpanExt; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; #[instrument] async fn do_work(val: u64) -> u64 { tokio::time::sleep(Duration::from_secs(1)).await; val + 1 } #[tokio::main] async fn main() { let indicatif_layer = IndicatifLayer::new(); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); // Create a header span with a custom progress bar style let header_span = info_span!("header"); header_span.pb_set_style(&ProgressStyle::with_template("{wide_bar} {pos}/{len} {msg}").unwrap()); header_span.pb_set_length(20); header_span.pb_set_message("Processing items"); header_span.pb_set_finish_message("All items processed"); let _guard = header_span.enter(); let res: u64 = stream::iter((0..20).map(|val| async move { let res = do_work(val).await; // Increment progress bar position from within the task Span::current().pb_inc(1); res })) .buffer_unordered(5) .collect::>() .await .into_iter() .sum(); println!("final result: {}", res); } ``` -------------------------------- ### Global Writer Access for Safe Output in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt The `get_indicatif_stderr_writer` and `get_indicatif_stdout_writer` functions provide global access to writers that safely interact with progress bars. This is useful in library functions or contexts where direct access to the `IndicatifLayer` instance is not available. ```rust use std::io::Write; use tracing_indicatif::writer::{get_indicatif_stderr_writer, get_indicatif_stdout_writer}; fn some_library_function() { // Access the writer without needing the IndicatifLayer instance if let Some(mut writer) = get_indicatif_stderr_writer() { writeln!(writer, "This won't clobber progress bars!").unwrap(); } if let Some(mut writer) = get_indicatif_stdout_writer() { writeln!(writer, "Safe stdout output").unwrap(); } } ``` -------------------------------- ### Suspend Progress Bars for Interactive Prompts in Rust Source: https://context7.com/emersonford/tracing-indicatif/llms.txt The `suspend_tracing_indicatif` function temporarily hides progress bars, enabling clean interactive input using libraries like `dialoguer`. This ensures that user prompts are displayed without interference from ongoing progress bar updates. ```rust use std::io::Write; use std::time::Duration; use dialoguer::Confirm; use tracing::info_span; use tracing_indicatif::IndicatifLayer; use tracing_indicatif::span_ext::IndicatifSpanExt; use tracing_indicatif::suspend_tracing_indicatif; use tracing_indicatif::writer::get_indicatif_stderr_writer; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; fn main() { let indicatif_layer = IndicatifLayer::new(); tracing_subscriber::registry() .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) .with(indicatif_layer) .init(); let span = info_span!("working"); span.pb_start(); std::thread::sleep(Duration::from_secs(1)); // Suspend progress bars for clean interactive dialogue suspend_tracing_indicatif(|| { if Confirm::new() .with_prompt("Do you like Rust?") .interact() .unwrap_or(false) { println!("Yay!"); } else { println!("oh... okay :("); } }); // Use the global stderr writer for safe output let _ = writeln!( get_indicatif_stderr_writer().unwrap(), "sleeping for some time..." ); std::thread::sleep(Duration::from_secs(1)); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.