Clap derive-style enums parsing

In Clap v3.1.6 when I define struct I can skip explicit declaration of attribute long name and it will be taken from the variable name:

use clap::Parser;

#[derive(Parser, Debug, PartialEq)]
#[clap(rename_all = "kebab_case")]
struct Opt {
    #[clap(long, // <-- here long name is implicitly set to `boo-boo` due to `rename_all`
    )]
    boo_boo: Boo,
}

Now the same parsing doesn't work with enums, so if I define enum like:

#[derive(Parser, Debug, PartialEq)]
#[clap(rename_all = "kebab_case")]
enum Boo {
    Aa,
    Bb,
}

It will return error that FromStr is not implemented.
It looks like I have to do some cumbersome constructions with manual parsing and specifying possible values:

#[derive(Parser, Debug, PartialEq)]
#[clap(rename_all = "kebab_case")]
struct Opt {
    #[clap(long,
        parse(try_from_str = boo_parser),
        possible_values = &["aa", "bb"]
    )]
    boo_boo: Boo,
}

fn boo_parser(s: &str) -> Result<Boo, &'static str> {
    match s {
        "aa" => Ok(Boo::Aa),
        "bb" => Ok(Boo::Bb),
        _ => Err("unsupported value"),
    }
}

#[derive(Parser, Debug, PartialEq)]
#[clap(rename_all = "kebab_case")]
enum Boo {
    Aa,
    Bb,
}

This way I have to implement my own parser and specify "aa" in two places without an option to rely on rename_all style.
The question is if there is something I've missed and if it is possible to simplify enums values parsing.

1 Like
use clap::{Parser, ArgEnum};

#[derive(Parser, Debug, Clone)]
struct Opt {
    #[clap(short, long, arg_enum)] // arg_enum here
    boo_boo: Boo,
}

#[derive(ArgEnum, Debug, Clone)] // ArgEnum here
#[clap(rename_all = "kebab_case")]
enum Boo {
    Aa,
    Bb,
}

Just adding ArgEnum and arg_enum should work, playground

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.