Skip to content

Add simple prompts #1634

@mayabyte

Description

@mayabyte

Maintainer's notes


Why?

Let's say you want to write a CLI program that requires the user to log in with a username and password, e.g. a CLI API for some web service. This is perfectly doable with arguments, but it may be preferred to prompt the user to supply these when they start the program, as follows:

$ example_program
> username: beepboop
> password: 
Successfully logged in!

Or, let's say you have an option that can be dangerous to enable in certain circumstances, and you want to ask the user if they're sure (like rm -rf does):

$ example_program --danger
> Are you sure you want to do the dangerous thing? [y/N] 

It's not hard to write this logic on your own, but given that these are rather common use-cases, it would be convenient to include this functionality within Clap.

What?

I propose adding a few simple prompting functions for handling common prompting situations. Here's a rough list:

  • prompt_if_absent(prompt: &str): Asks the user to supply a value for this argument if they didn't at run time. Displays prompt on the line where they type; in the first example above, the prompts would have been "> username: " and "> password: " respectively.
  • suggest_if_absent(prompt: &str, default: Fn() -> Option<String>): Like prompt_if_absent, but takes a function that can try to find a sensible default to suggest to the user, which can then be chosen by pressing enter without typing. Useful when you're not sure the default makes sense (e.g. if it's found from an envar or something), so you want to run it by the user to make sure.
  • ensure_if(prompt: &str, arg_id: Key, val: &str, default: Yes/No/None) and similar ensure_ifs: Asks the user if they're sure when they've set val(s) with a [y/n] prompt. The user can select the default option by just pressing enter.
  • prompt_secret(prompt: &str): like prompt_if_absent but doesn't show what you're typing

These can all be gated behind a prompts feature or something to keep the core functionality simple.

I realise there's been a little pushback on stuff like this in the past (~a few years ago?), but I do genuinely think it would be a nice addition. A lot of great CLI building tools in other languages include prompting functionality, so adding a few convenience methods for it reduces the friction required to port existing things over to Rust.

I'm happy to implement this myself if there's interest.

(Note: I'm aware of #1471, but the changes they suggest are much more significant and have potentially quite wide implications, so I consider it a separate matter. I'd love to see that get added though :P)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-parsingArea: Parser's logic and needs it changed somehow.C-enhancementCategory: Raise on the bar on expectationsS-blockedStatus: Blocked on something else such as an RFC or other implementation work.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions