如何使用 Clap“展平”子命令

Typ*_*aon 5 rust clap

我的程序中有两种类型的命令,我想将其中一种类型分组到一个枚举中。我不希望用户必须输入额外的内容,所以我想在顶层公开这些命令。如何“扁平化”子命令?

目前我正在使用以下(简化的)代码

use clap::{Parser, Subcommand};

#[derive(Parser, Debug)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Commands,
}


#[derive(Debug, Subcommand)]
#[non_exhaustive]
pub enum Commands {
    ChangeBrightness{ 
        #[command(subcommand)] 
        command: ChangeBrightnessCommand,
        #[arg(short, long)]
        devices: Vec<String>
    },
    List,
}

#[derive(Debug, Subcommand)]
pub enum ChangeBrightnessCommand {
    Set { 
        #[arg(value_parser = clap::value_parser!(u8).range(0..=100))] 
        percent: u8,
    },
    Get,
    // There are more (like increment, decrement, set-max, and set-min)
}

fn main() {
    let cli = Cli::parse();
    println!("{:?}", cli);
    match &cli.command {
        Commands::ChangeBrightness{command, devices} => todo!(),
        Commands::List => todo!()
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我当前运行时的输出:

% target/debug/test-clap                  
Usage: test-clap <COMMAND>
Commands:
  change-brightness  
  list               
  help               Print this message or the help of the given subcommand(s)

% target/debug/test-clap change-brightness
Usage: test-clap change-brightness [OPTIONS] <COMMAND>

Commands:
  set   
  get   
  help  Print this message or the help of the given subcommand(s)

Options:
  -d, --devices <DEVICES>
  -h, --help               Print help
Run Code Online (Sandbox Code Playgroud)

这是我想要的输出的草图:

% target/debug/test-clap                 
Usage: test-clap <COMMAND> [OPTIONS]
Commands:
  set
  get 
  list               
  help               Print this message or the help of the given subcommand(s)
Run Code Online (Sandbox Code Playgroud)

这意味着这些应该是对程序的所有有效调用:

% target/debug/test-clap set 100 --devices dev0 dev1 dev2
% target/debug/test-clap get -d dev0 dev1 dev2
% target/debug/test-clap set 5
% target/debug/test-clap get --devices dev0
% target/debug/test-clap list
Run Code Online (Sandbox Code Playgroud)

我也尝试过#[command(flatten)],但我会收到以下错误:

error[E0277]: the trait bound `ChangeBrightnessCommand: clap::Args` is not satisfied
  --> src/main.rs:13:33
   |
13 |     ChangeBrightness{ #[command(flatten)] command: ChangeBrightnessCommand,#[arg(s...
   |                                 ^^^^^^^ the trait `clap::Args` is not implemented for `ChangeBrightnessCommand`
Run Code Online (Sandbox Code Playgroud)