2 releases
0.0.2 | Aug 26, 2021 |
---|---|
0.0.1 | Aug 12, 2021 |
#770 in Command-line interface
45KB
643 lines
asking
Build async prompts.
About
Ever wanted non-blocking user input? Here you are!
Asynchronous I/O is a form of input/output processing that allows you to do something while waiting for an answer.
Features
- Asynchronous - You can work while the user inputs something and even timeout!
- Common patterns - Built-in common question patterns including
- yn - yes/no questions (see
yn
function). - date - dates in
%Y-%m-%d
format (seedate
function). - select - choose one option (see
inside
method). - text - just a String (see
text
function). - T - your own type! (implementing or not the trait
FromStr
).
- yn - yes/no questions (see
- Cross-platform - Generic on writer and reader!
- Help messages - Help the user to input a correct answer.
- Test with feedback - Test the input and, optionally, give feedback upon errors.
- Default values - Add a value for empty inputs.
- Standardized error handling - You can manage errors!
- Feedback - Display a final message depending on the accepted value.
- Extensive documentation - If you do not think so, let me know!
Limitations
- Internal mutability of functions - All functions are stored as
Arc<dyn Fn>
. This allows both functions and closures, but it means that functions can not hold any mutable references (so no internal mutability). - Send + Sync + 'static - To allow asynchronous execution, at the end of the day, all parameters have to implement this traits. This way you can truly harness async execution of questions. If you manage to use something that does not implement these traits, then the future can only be executed synchronously.
- Consuming methods - Methods are consuming allowing one-line constructions, while making more difficult complex construction patterns. This is because of the existence of default values. Check out C-BUILDER.
Let me know if you find anything else, I will be happy to add it!
Quick example
Give only five seconds to the user to confirm something, and continue upon no input! (instead of keep waiting)
use asking::error::Processing;
use std::time::Duration;
let question = asking::yn()
.message("Shall I continue? (you have 5 seconds to answer)")
.default_value(true) // value upon empty input
.timeout(Duration::from_secs(5_u64))
.ask();
match async_std::task::block_on(question) { // we decide to just wait, at most five secs
Ok(true) => println!("Super!"),
Ok(false) => println!("Okay, shutting down..."),
Err(Processing::Timeout { .. }) => println!("I think you are not here, I will continue :)"), // Automatic decision!,
_ => eprintln!("Error with questionnaire, try again later"),
}
Check out more examples!
Usage
With cargo-edit installed, simply type
cargo add asking
and you are good to go!
Related crates
There are several crates for handling user input, I recommend checking them all out!
- ask A simple toolset for asking questions through the terminal.
- dialoguer A command line prompting library.
- inquire Library for building interactive prompts on terminals.
- promptly Simple, opinionated CLI prompting helper.
- requestty An easy-to-use collection of interactive cli prompts.
- rprompt Prompt user input in console applications.
- question Ask a question, what more could you want?
- read_input A simple CLI tool that asks for user input until the data inputted is valid.
- termion::AsyncReader An asynchronous reader.
- timeout-readwrite Adds timeout capabilities to Readers and Writers.
If you've got a crate that would be a good fit, open an issue and let me know. I'd love to add it!
Good matchups
Some crates are good to use together!
- async-dup - Duplicate an I/O handle
FAQ
Testing
Testing projects with user input can be challenging.
- How to give input to Stdin and read from Stdout?
The easiest way is using the
assert_cmd
crate. Check out- Example
testing
. - Folder
tests
of this repository. - For more, go to Command line apps in Rust book.
- Example
Dependencies
~5–15MB
~200K SLoC