A prompt library for Rust. Based on huh? for Go. Maintained by @jdx and @roele.
- Single-line text input with variable prompt and placeholder
 - Auto-complete suggestions with 
TAB - Validate input with a custom closure
 
Run example with cargo run --example input.
use demand::Input;
fn main() {
    let notempty_minlen = |s: &str| {
        if s.is_empty() {
            return Err("Name cannot be empty");
        }
        if s.len() < 8 {
            return Err("Name must be at least 8 characters");
        }
        Ok(())
    };
    let t = Input::new("What's your name?")
        .description("We'll use this to personalize your experience.")
        .placeholder("Enter your name")
        .prompt("Name: ")
        .suggestions(vec![
            "Adam Grant",
            "Danielle Steel",
            "Eveline Widmer-Schlumpf",
            "Robert De Niro",
            "Ronaldo Rodrigues de Jesus",
            "Sarah Michelle Gellar",
            "Yael Naim",
            "Zack Snyder",
        ])
        .validation(notempty_minlen);
    let i = t.run().expect("error running input");
}Run example with cargo run --example input-password.
use demand::Input;
fn main() {
    let t = Input::new("Set a password")
        .placeholder("Enter password")
        .prompt("Password: ")
        .password(true);
    let i = t.run().expect("error running input");
}Shows a list of options. Run example with cargo run --example list.
use demand::List;
fn main() {
    let list = List::new("Toppings")
        .description("List of available toppings")
        .item("Lettuce")
        .item("Tomatoes")
        .item("Charm Sauce")
        .item("Jalapenos")
        .item("Cheese")
        .item("Vegan Cheese")
        .item("Nutella")
        .item("Peanut Butter")
        .item("Banana")
        .filterable(true);
    list.run().expect("error running list")
}Select from a list of options.
Run example with cargo run --example select.
use demand::{DemandOption, Select};
fn main() {
    let ms = Select::new("Toppings")
        .description("Select your topping")
        .filterable(true)
        .option(DemandOption::new("Lettuce").description("Fresh and crispy"))
        .option(DemandOption::new("Tomatoes").description("Juicy and red"))
        .option(DemandOption::new("Charm Sauce").description("Our secret recipe"))
        .option(DemandOption::new("Jalapenos").label("Jalapeños").description("Spicy and hot"))
        .option(DemandOption::new("Cheese").description("Melted and gooey"))
        .option(DemandOption::new("Vegan Cheese").description("Melted and gooey"))
        .option(DemandOption::new("Nutella").description("Sweet and creamy"));
    ms.run().expect("error running select");
}Select multiple options from a list.
Run example with cargo run --example multiselect.
use demand::{DemandOption, MultiSelect};
fn main() {
    let ms = MultiSelect::new("Toppings")
        .description("Select your toppings")
        .min(1)
        .max(4)
        .filterable(true)
        .option(DemandOption::new("Lettuce").selected(true))
        .option(DemandOption::new("Tomatoes").selected(true))
        .option(DemandOption::new("Charm Sauce"))
        .option(DemandOption::new("Jalapenos").label("Jalapeños"))
        .option(DemandOption::new("Cheese"))
        .option(DemandOption::new("Vegan Cheese"))
        .option(DemandOption::new("Nutella"));
    ms.run().expect("error running multi select");
}Confirm a question with a yes or no.
Run example with cargo run --example confirm.
use demand::Confirm;
fn main() {
    let ms = Confirm::new("Are you sure?")
        .affirmative("Yes!")
        .negative("No.");
    let yes = ms.run().expect("error running confirm");
}Show a dialog with multiple buttons.
Run example with cargo run --example dialog.
use demand::{Dialog, DialogButton};
fn main() {
    let ms = Dialog::new("Are you sure?")
        .description("This will do a thing.")
        .buttons(vec![
            DialogButton::new("Ok"),
            DialogButton::new("Not sure"),
            DialogButton::new("Cancel"),
        ])
        .selected_button(1);
    ms.run().expect("error running confirm");
}Spinners are used to indicate that a process is running.
Run example with cargo run --example spinner.
use std::{thread::sleep, time::Duration};
use demand::{Spinner, SpinnerStyle};
fn main() {
    Spinner::new("Loading Data...")
        .style(SpinnerStyle::line())
        .run(|| {
            sleep(Duration::from_secs(2));
        })
        .expect("error running spinner");
}Supply your own custom theme or choose from one of the predefined themes:
Derive a custom theme from the default theme.
let theme = Theme {
    selected_prefix: String::from(" •"),
    selected_prefix_fg: Theme::color_rgb(2, 191, 135),
    unselected_prefix: String::from("  "),
    ..Theme::default()
};
Input::new("What's your e-mail?")
        .description("Please enter your e-mail address.")
        .placeholder("[email protected]")
        .theme(&theme)
        .run()
        .expect("error running input")?;Default if colors are enabled in the console.
Default if colors are NOT enabled in the console.
The name of this library is inspired by a great mistranslation that soured US-French relations in 1830. In French, the verb "demander" means "to ask".












