3

I'd like to use ArgAction::Count to count the number of occurrences of my --verbose flag, and then send the result through a closure to convert it to a Verbosity enum.

At the moment I'm trying this:

use clap::{Parser, ArgAction, builder::TypedValueParser};

#[derive(Debug, Parser)]
struct Cli {
    #[arg(short, long, action = ArgAction::Count, value_parser(
        clap::value_parser!(u8)
            .map(|v| match v {
                0 => Verbosity::Low,
                1 => Verbosity::Medium,
                _ => Verbosity::High,
            })
    ))]
    verbose: Verbosity,
}

#[derive(Debug, Clone)]
enum Verbosity {
    Low,
    Medium,
    High,
}

fn main() {
    dbg!(Cli::parse());
}

But this panics at runtime:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `u8`,
 right: `clap_question::Verbosity`: Argument `verbose`'s selected action Count contradicts `value_parser` (ValueParser::other(clap_question::Verbosity))

Is there any way to make this work?

  • 1
    I'm not sure you can do this. Why not add an `impl Cli` that has a `verbosity_level()` function that does this conversion? – tadman Feb 28 '23 at 21:35
  • @tadman that does work, but isn't as clean and declarative as it could be. And it does seem like this should be possible! The docs for [`map`](https://docs.rs/clap/latest/clap/builder/trait.TypedValueParser.html#method.map) have an example of something similar, and the [implementation of `MapValueParser`](https://docs.rs/clap/latest/src/clap/builder/value_parser.rs.html#1971-1980) shows that it does what I thought it did – uses the original parser and then applies the function to the result. – Will Burden Mar 01 '23 at 17:14
  • I've been using Clap for a while now, and it's pretty capable, but the one thing that's consistently frustrating is how obtuse some of the declarations are, and how patchy the documentation can be. Could you write a custom `action` handler here? Maybe a `Verbosity` method that can increment itself as a start, or `impl Add`. – tadman Mar 01 '23 at 17:36

0 Answers0