User interaction
Recipe | Crates | Categories |
---|---|---|
Ask for confirmation, selection, text input | ||
Display progress bars and spinners |
Ask for confirmation, selection, text input
inquire
provides several different prompts in order to interactively ask the user for information via the CLI.
use inquire::Confirm; use inquire::Select; use inquire::Text; // The `inquire`` crate is used for creating interactive CLI prompts. fn main() { let ans = Confirm::new("Do you want to proceed?") .with_default(false) .prompt() .expect("Failed to read input"); println!("You answered: {:?}", ans); // Prompt for the user's name let name = Text::new("What's your name?") .prompt() .expect("Failed to read input"); // Prompt for the user's favorite programming language let languages = vec!["Rust", "Python", "JavaScript", "C++", "Go", "Other"]; let favorite_language = Select::new("What's your favorite programming language?", languages) //.with_help_message("Hint: it is Rust!") .prompt() .expect("Failed to read input"); // Display the collected information println!("Hello, {}!", name); println!( "Your favorite programming language is {}.", favorite_language ); }
Display progress bars and spinners
indicatif
⮳ is a Rust library for indicating progress in command line applications to users.
This currently primarily provides progress bars and spinners as well as basic color support.
use std::thread;
use std::time::Duration;
use console::Emoji;
use console::Style;
use console::Term;
use indicatif::ProgressBar;
use indicatif::ProgressStyle;
fn spinner() -> anyhow::Result<()> {
// `console` is a library for Rust that provides access to
// terminal features, like styles and colors.
// The terminal is abstracted through the `console::Term` type.
let term = Term::stdout();
term.clear_screen()?;
term.write_line("Simulate the output of a compiler:")?;
thread::sleep(Duration::from_millis(20));
term.clear_line()?;
// Print with styles / colors
println!(
"Target: {}",
console::style("x86_64-unknown-linux-gnu").cyan()
);
// `indicatif` offers progress bars and spinners.
// Create a progress bar with an indeterminate length:
let pb = ProgressBar::new_spinner();
pb.set_style(
ProgressStyle::default_spinner()
.template("{spinner:.green} [{elapsed_precise}] {msg}")
.expect("Failed to set progress style"),
);
// Simulate different stages of the compilation process
let stages = vec![
("Parsing source files", 1),
("Type checking", 3),
("Optimizing code", 2),
("Generating bytecode", 1),
("Linking objects", 1),
("Finalizing build", 1),
];
// Spawns a background thread to tick the progress bar
pb.enable_steady_tick(Duration::from_millis(100));
for (stage, duration) in stages {
pb.set_message(stage);
thread::sleep(Duration::from_secs(duration));
}
pb.disable_steady_tick();
pb.finish_with_message("Compilation complete!");
// Print with style
let cyan = Style::new().cyan();
println!("Executable: {}", cyan.apply_to("./target/debug/my_program"));
// Use emojis
println!("{} Done!", Emoji("✨", ":-)"));
Ok(())
}
fn main() -> anyhow::Result<()> {
spinner()?;
Ok(())
}
use std::thread;
use std::time::Duration;
use indicatif::ProgressBar;
use indicatif::ProgressStyle;
fn progress() {
// Create a new progress bar with a length of 100
// This progress bar by default draws directly to stderr.
// If a non terminal is detected,
// the progress bar will be completely hidden.
let pb = ProgressBar::new(100);
// Set a custom style for the progress bar
pb.set_style(ProgressStyle::default_bar()
// 40 characters wide and has cyan as primary style color and blue as alternative style color.
.template("{spinner:.green} [{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}")
.unwrap()
.progress_chars("=>."));
for _ in 0..100 {
// Update the progress bar
pb.inc(1);
// Simulate work by sleeping for a short duration
thread::sleep(Duration::from_millis(50));
}
// Finish the progress bar
pb.finish_with_message("done"); // or use .finish();
// Alternatively, you could wrap an iterator with a progress bar:
// use indicatif::ProgressIterator;
// for _ in (0..100).progress() {
// thread::sleep(Duration::from_millis(50));
// }
}
fn main() -> anyhow::Result<()> {
progress();
Ok(())
}
[user_interaction: write (P1)](https://github.com/john-cd/rust_howto/issues/235)