diff --git a/README.md b/README.md index 2eb7ede..7348aa7 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,164 @@ Best paired with other libraries in the family: * [console](https://github.com/console-rs/console) * [indicatif](https://github.com/console-rs/indicatif) +## Usage + +Add the library to your `Cargo.toml`: + +```shell +cargo add dialoguer +``` + +## Examples + +### Confirm + +Docs: [dialoguer::Confirm](https://docs.rs/dialoguer/latest/dialoguer/struct.Confirm.html) + +```rust +use dialoguer::{theme::ColorfulTheme, Confirm}; + +if Confirm::with_theme(&ColorfulTheme::default()) + .with_prompt("Do you want to continue?") + .interact()? +{ + println!("Looks like you want to continue"); +} +``` + +![confirm](https://vhs.charm.sh/vhs-5ianSRV6gBIQw8zHbXZs7X.gif) + +With a default value: + +```rust +use dialoguer::{theme::ColorfulTheme, Confirm}; + +if Confirm::new() + .with_prompt("Do you want to continue?") + .default(true) + .interact()? +{ + println!("Looks like you want to continue"); +} +``` + +![confirm-with-default](https://vhs.charm.sh/vhs-KumYDsqM2KSxaMUHRr8IV.gif) + +## Input + +Docs: [dialoguer::Input](https://docs.rs/dialoguer/latest/dialoguer/struct.Input.html) + +```rust +use dialoguer::{theme::ColorfulTheme, Input}; + +let name: String = dialoguer::Input::with_theme(&ColorfulTheme::default()) + .with_prompt("What is your name?") + .interact()?; +println!("Hello, {name}"); +``` + +![input](https://vhs.charm.sh/vhs-7EYUy5VCybcotdxrL8QCXk.gif) + +## Password + +Docs: [dialoguer::Password](https://docs.rs/dialoguer/latest/dialoguer/struct.Password.html) + +```rust +use dialoguer::{theme::ColorfulTheme, Password}; + +let password: String = Password::with_theme(&ColorfulTheme::default()) + .with_prompt("Enter your password") + .interact()?; +println!("Your password is: {password}"); +``` + +![password](https://vhs.charm.sh/vhs-1HTgKYmFc09dNtuHu5hWOO.gif) + +## Editor + +Docs: [dialoguer::Editor](https://docs.rs/dialoguer/latest/dialoguer/struct.Editor.html) + +```rust +use dialoguer::Editor; + +match dialoguer::Editor::new().edit("Some content")? { + Some(content) => println!("Content: {content:?}"), + None => println!("File was not saved"), +} +``` + +![editor](https://vhs.charm.sh/vhs-3DISbkWUNwMms076djOQ3e.gif) + +## Select + +Docs: [dialoguer::Select](https://docs.rs/dialoguer/latest/dialoguer/struct.Select.html) + +```rust +use dialoguer::{theme::ColorfulTheme, Select}; + +let items = vec!["Apple", "Banana", "Cherry"]; +let selection = Select::with_theme(&ColorfulTheme::default()) + .with_prompt("What is your favourite fruit?") + .items(&items) + .interact()?; +println!("You picked: {selection}", selection = items[selection]); +``` + +![select](https://vhs.charm.sh/vhs-3ylAvmWOIiBkYexnG7j4F9.gif) + +## FuzzySelect + +Docs: [dialoguer::FuzzySelect](https://docs.rs/dialoguer/latest/dialoguer/struct.FuzzySelect.html) + +```rust +use dialoguer::{theme::ColorfulTheme, FuzzySelect}; + +let items = vec!["Apple", "Banana", "Cherry"]; +let selection = FuzzySelect::with_theme(&ColorfulTheme::default()) + .with_prompt("What is your favourite fruit?") + .items(&items) + .interact()?; +println!("You picked: {selection}", selection = items[selection]); +``` + +![fuzzy-select](https://vhs.charm.sh/vhs-3JUdbUNwnUKWVjk6J5XoKh.gif) + +## MultiSelect + +Docs: [dialoguer::MultiSelect](https://docs.rs/dialoguer/latest/dialoguer/struct.MultiSelect.html) + +```rust +use dialoguer::{theme::ColorfulTheme, MultiSelect}; + +let items = vec!["Apple", "Banana", "Cherry"]; +let selection = MultiSelect::with_theme(&ColorfulTheme::default()) + .with_prompt("What are your favourite fruits?") + .items(&items) + .interact()?; +let selected_items: Vec<_> = selection.iter().map(|i| items[*i]).collect(); +println!("You picked: {selected_items:?}"); +``` + +![multi-select](https://vhs.charm.sh/vhs-5Jje1Pdxsw4w5jLJjeWNbI.gif) + +## Sort + +Docs: [dialoguer::Sort](https://docs.rs/dialoguer/latest/dialoguer/struct.Sort.html) + +```rust +use dialoguer::{theme::ColorfulTheme, Sort}; + +let items = vec!["Apple", "Banana", "Cherry"]; +let selection = Sort::with_theme(&ColorfulTheme::default()) + .with_prompt("Sort the fruits") + .items(&items) + .interact()?; +let sorted_items: Vec<_> = selection.iter().map(|i| items[*i]).collect(); +println!("You sorted: {sorted_items:?}"); +``` + +![sort](https://vhs.charm.sh/vhs-mcxq0aABXECgIdafLBNZN.gif) + ## License and Links * [Documentation](https://docs.rs/dialoguer/) diff --git a/examples/readme.rs b/examples/readme.rs new file mode 100644 index 0000000..178e695 --- /dev/null +++ b/examples/readme.rs @@ -0,0 +1,122 @@ +//! The purpose of this example is to provide simple examples of how to use each of the dialoguer +//! prompts. + +use std::{env::args, thread, time::Duration}; + +#[cfg(feature = "fuzzy-select")] +use dialoguer::FuzzySelect; +use dialoguer::{theme::ColorfulTheme, Confirm, MultiSelect, Password, Select, Sort}; + +fn main() -> dialoguer::Result<()> { + match args().nth(1) { + None => println!("No argument provided"), + Some(arg) => run(arg)?, + } + Ok(()) +} + +fn run(arg: String) -> Result<(), dialoguer::Error> { + match arg.as_str() { + "confirm" => confirm()?, + "confirm-with-default" => confirm_with_default()?, + "input" => input()?, + "password" => password()?, + "editor" => editor()?, + "select" => select()?, + "multi-select" => multi_select()?, + #[cfg(feature = "fuzzy-select")] + "fuzzy-select" => fuzzy_select()?, + "sort" => sort()?, + _ => println!("Invalid argument"), + } + thread::sleep(Duration::from_secs(3)); // give the VHS tape time to capture the effect + Ok(()) +} + +fn confirm() -> dialoguer::Result<()> { + if Confirm::with_theme(&ColorfulTheme::default()) + .with_prompt("Do you want to continue?") + .interact()? + { + println!("Looks like you want to continue"); + } + Ok(()) +} + +fn confirm_with_default() -> dialoguer::Result<()> { + if Confirm::with_theme(&ColorfulTheme::default()) + .with_prompt("Do you want to continue?") + .default(true) + .interact()? + { + println!("Looks like you want to continue"); + } + Ok(()) +} + +fn input() -> dialoguer::Result<()> { + let name: String = dialoguer::Input::with_theme(&ColorfulTheme::default()) + .with_prompt("What is your name?") + .interact()?; + println!("Hello, {name}"); + Ok(()) +} + +fn password() -> dialoguer::Result<()> { + let password: String = Password::with_theme(&ColorfulTheme::default()) + .with_prompt("Enter your password") + .interact()?; + println!("Your password is: {password}"); + Ok(()) +} + +fn editor() -> dialoguer::Result<()> { + match dialoguer::Editor::new().edit("Some content")? { + Some(content) => println!("Content: {content:?}"), + None => println!("File was not saved"), + } + Ok(()) +} + +fn select() -> dialoguer::Result<()> { + let items = vec!["Apple", "Banana", "Cherry"]; + let selection = Select::with_theme(&ColorfulTheme::default()) + .with_prompt("What is your favourite fruit?") + .items(&items) + .interact()?; + println!("You picked: {selection}", selection = items[selection]); + Ok(()) +} + +#[cfg(feature = "fuzzy-select")] +fn fuzzy_select() -> dialoguer::Result<()> { + let items = vec!["Apple", "Banana", "Cherry"]; + let selection = FuzzySelect::with_theme(&ColorfulTheme::default()) + .with_prompt("What is your favourite fruit?") + .items(&items) + .interact()?; + println!("You picked: {selection}", selection = items[selection]); + Ok(()) +} + +fn multi_select() -> dialoguer::Result<()> { + let items = vec!["Apple", "Banana", "Cherry"]; + let selection = MultiSelect::with_theme(&ColorfulTheme::default()) + .with_prompt("What are your favourite fruits?") + .items(&items) + .interact()?; + let selected_items: Vec<_> = selection.iter().map(|i| items[*i]).collect(); + println!("You picked: {selected_items:?}"); + Ok(()) +} + +fn sort() -> dialoguer::Result<()> { + let items = vec!["Apple", "Banana", "Cherry"]; + let selection = Sort::with_theme(&ColorfulTheme::default()) + .with_prompt("Sort the fruits") + .items(&items) + .interact()?; + let sorted_items: Vec<_> = selection.iter().map(|i| items[*i]).collect(); + println!("You sorted: {sorted_items:?}"); + Ok(()) +} diff --git a/examples/vhs/confirm-with-default.tape b/examples/vhs/confirm-with-default.tape new file mode 100644 index 0000000..93e0f7a --- /dev/null +++ b/examples/vhs/confirm-with-default.tape @@ -0,0 +1,12 @@ +Output target/confirm-with-default.gif + +Set Width 1200 +Set Height 250 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme confirm-with-default" Enter +Show +Sleep 2s +Enter +Sleep 2s diff --git a/examples/vhs/confirm.tape b/examples/vhs/confirm.tape new file mode 100644 index 0000000..cd9349f --- /dev/null +++ b/examples/vhs/confirm.tape @@ -0,0 +1,12 @@ +Output target/confirm.gif + +Set Width 1200 +Set Height 250 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme confirm" Enter +Show +Sleep 2s +Type "y" +Sleep 2s diff --git a/examples/vhs/editor.tape b/examples/vhs/editor.tape new file mode 100644 index 0000000..85130df --- /dev/null +++ b/examples/vhs/editor.tape @@ -0,0 +1,13 @@ +Output target/editor.gif + +Set Width 1200 +Set Height 250 +Set Theme "Aardvark Blue" + +Hide +Type "EDITOR=vim cargo run --quiet --example readme editor" Enter +Show +Sleep 2s +Type "CHello, World!" Escape +Type "ZZ" +Sleep 2s diff --git a/examples/vhs/fuzzy-select.tape b/examples/vhs/fuzzy-select.tape new file mode 100644 index 0000000..838b0d1 --- /dev/null +++ b/examples/vhs/fuzzy-select.tape @@ -0,0 +1,17 @@ +Output target/fuzzy-select.gif + +Set Width 1200 +Set Height 350 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme --features=fuzzy-select fuzzy-select" Enter +Show +Sleep 2s +Type "a" +Sleep 1s +Down +Sleep 1s +Enter + +Sleep 2s diff --git a/examples/vhs/input.tape b/examples/vhs/input.tape new file mode 100644 index 0000000..74eedcf --- /dev/null +++ b/examples/vhs/input.tape @@ -0,0 +1,12 @@ +Output target/input.gif + +Set Width 1200 +Set Height 250 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme input" Enter +Show +Sleep 2s +Type "pksunkara" Enter +Sleep 2s diff --git a/examples/vhs/multi-select.tape b/examples/vhs/multi-select.tape new file mode 100644 index 0000000..173c33e --- /dev/null +++ b/examples/vhs/multi-select.tape @@ -0,0 +1,21 @@ +Output target/multi-select.gif + +Set Width 1200 +Set Height 350 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme multi-select" Enter +Show +Sleep 2s +Down +Sleep 1s +Space +Sleep 1s +Down +Sleep 1s +Space +Sleep 1s +Enter + +Sleep 2s diff --git a/examples/vhs/password.tape b/examples/vhs/password.tape new file mode 100644 index 0000000..d3352de --- /dev/null +++ b/examples/vhs/password.tape @@ -0,0 +1,12 @@ +Output target/input.gif + +Set Width 1200 +Set Height 250 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme password" Enter +Show +Sleep 2s +Type "Password123!" Enter +Sleep 2s diff --git a/examples/vhs/publish-all.sh b/examples/vhs/publish-all.sh new file mode 100755 index 0000000..32535a8 --- /dev/null +++ b/examples/vhs/publish-all.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Publish all VHS examples to the VHS website. +# requires https://github.com/charmbracelet/vhs to be installed + +examples=( + confirm + confirm-with-default + input + password + editor + select + fuzzy-select + multi-select + sort +) +for example in "${examples[@]}"; do + echo "Publishing ${example}..." + vhs --quiet --publish examples/vhs/${example}.tape +done diff --git a/examples/vhs/select.tape b/examples/vhs/select.tape new file mode 100644 index 0000000..9851168 --- /dev/null +++ b/examples/vhs/select.tape @@ -0,0 +1,17 @@ +Output target/select.gif + +Set Width 1200 +Set Height 350 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme select" Enter +Show +Sleep 2s +Down +Sleep 1s +Down +Sleep 1s +Enter + +Sleep 2s diff --git a/examples/vhs/sort.tape b/examples/vhs/sort.tape new file mode 100644 index 0000000..8cac969 --- /dev/null +++ b/examples/vhs/sort.tape @@ -0,0 +1,21 @@ +Output target/select.gif + +Set Width 1200 +Set Height 350 +Set Theme "Aardvark Blue" + +Hide +Type "cargo run --quiet --example readme sort" Enter +Show +Sleep 2s +Space +Sleep 1s +Down +Sleep 1s +Down +Sleep 1s +Up +Sleep 1s +Enter + +Sleep 2s