all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: Gabriel Goller <g.goller@proxmox.com>
Cc: pbs-devel@lists.proxmox.com
Subject: Re: [pbs-devel] [PATCH proxmox v3] router: cli: added `ask_for_confirmation` helper
Date: Wed, 27 Sep 2023 12:13:51 +0200	[thread overview]
Message-ID: <lbrdijo53uap4k7vp6d7sqlqu3upfjh6eieps777xwb5bms7uy@dg6hfnorqooa> (raw)
In-Reply-To: <20230908114409.178087-2-g.goller@proxmox.com>

On Fri, Sep 08, 2023 at 01:44:09PM +0200, Gabriel Goller wrote:
> Added `ask_for_confirmation` helper that outputs a prompt and
> lets the user confirm or deny it. Also added localization using
> `libc::nl_langinfo()` to match/show a `yes` or `no` in the correct
> language.
> Implemented to close #4763.
> 
> Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
> ---
> 
> update v3:
>  - added localization using `libc::nl_langinfo`
> 
> note: skipped to version 3, so that the whole patch series has 
>       the same version number.
> 
>  proxmox-router/Cargo.toml     |  1 +
>  proxmox-router/src/cli/mod.rs | 34 +++++++++++++++++++++++++++++++++-
>  2 files changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/proxmox-router/Cargo.toml b/proxmox-router/Cargo.toml
> index 1c08ce2..e0d67d0 100644
> --- a/proxmox-router/Cargo.toml
> +++ b/proxmox-router/Cargo.toml
> @@ -19,6 +19,7 @@ percent-encoding.workspace = true
>  serde_json.workspace = true
>  serde.workspace = true
>  unicode-width ="0.1.8"
> +regex.workspace = true
>  
>  # cli:
>  tokio = { workspace = true, features = [], optional = true }
> diff --git a/proxmox-router/src/cli/mod.rs b/proxmox-router/src/cli/mod.rs
> index 208df4a..1dcfaf0 100644
> --- a/proxmox-router/src/cli/mod.rs
> +++ b/proxmox-router/src/cli/mod.rs
> @@ -12,7 +12,10 @@
>  //! - Ability to create interactive commands (using ``rustyline``)
>  //! - Supports complex/nested commands
>  
> -use std::collections::HashMap;
> +use std::{
> +    collections::HashMap,
> +    io::{self, Write},
> +};
>  
>  use crate::ApiMethod;
>  
> @@ -62,6 +65,35 @@ pub fn init_cli_logger(env_var_name: &str, default_log_level: &str) {
>      .init();
>  }
>  
> +pub fn ask_for_confirmation(query: String) -> Result<(), io::Error> {

IMO a generic helper should take the default as parameter (to decide on
the upper/lower-casing, see below), and also return a boolean for the
result. The Err case should be exclusively for actual errors (from
`.read_line()`).

> +    use std::ffi::CStr;
> +    let yes_expr = unsafe { CStr::from_ptr(libc::nl_langinfo(libc::YESEXPR)) }
> +        .to_str()
> +        .unwrap_or("^[yY]$");
> +    let no_expr = unsafe { CStr::from_ptr(libc::nl_langinfo(libc::NOEXPR)) }
> +        .to_str()
> +        .unwrap_or("^[nN]$");
> +
> +    let n = no_expr.chars().find(|c| c.is_uppercase()).unwrap_or('N');
> +    let y = yes_expr.chars().find(|c| c.is_uppercase()).unwrap_or('Y');
> +    print!("{query} [{y}/{n}]: ");

Usually, the uppercase letter is used for the default for when typing
nothing, while the other one is lowercase.

Now I was also wondering what we should do if no upper/lowercase letter
exists, but then again, it seems yY and nN are pretty much always
included. I checked at least de_DE, ja_JP and zh_CN next to en_US, and
I'm fairly certain we can rely on that, since I'm assuming this is
exactly what `rpmatch(3)` does, which explicitly states that `y` and `n`
work regardless of locale.

> +
> +    use regex::Regex;
> +    // .unwrap() is okay, because we should always get a correct regex (see `.unwrap_or()` calls above)
> +    let yes_regex: Regex = Regex::new(yes_expr).unwrap();

It might be worth caching this in a static `OnceCell`.

> +
> +    io::stdout().flush()?;
> +    let stdin = io::stdin();
> +    let mut line = String::new();
> +    stdin.read_line(&mut line)?;
> +
> +    if yes_regex.is_match(line.trim()) {
> +        Ok(())
> +    } else {
> +        Err(io::Error::new(io::ErrorKind::Other, "Aborted"))
> +    }
> +}
> +
>  /// Define a simple CLI command.
>  pub struct CliCommand {
>      /// The Schema definition.
> -- 
> 2.39.2




  reply	other threads:[~2023-09-27 10:13 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-08 11:44 [pbs-devel] [PATCH proxmox-backup v3] close #4763: client: added command to forget backup group Gabriel Goller
2023-09-08 11:44 ` [pbs-devel] [PATCH proxmox v3] router: cli: added `ask_for_confirmation` helper Gabriel Goller
2023-09-27 10:13   ` Wolfgang Bumiller [this message]
2023-09-27 10:48     ` Fabian Grünbichler
2023-09-27 14:45       ` Gabriel Goller
2023-12-07 12:51 ` [pbs-devel] [PATCH proxmox-backup v3] close #4763: client: added command to forget backup group Gabriel Goller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=lbrdijo53uap4k7vp6d7sqlqu3upfjh6eieps777xwb5bms7uy@dg6hfnorqooa \
    --to=w.bumiller@proxmox.com \
    --cc=g.goller@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal