clapを使って、Subcommandをネストする

やりたいこと

こういう感じで、hoge <subcommand> <sub-subcommand>なCLIを作りたかった。

hoge fuga piyo

こうすれば行けた

clapのCookbookを読めば解決した。

docs.rs

最小構成はこうなった。

use clap::{Args, Parser, Subcommand};

#[derive(Parser, Debug)]
#[command(name = "hoge")]
struct Cli {
    #[command(subcommand)]
    command: HogeCommands,
}

#[derive(Debug, Subcommand)]
enum HogeCommands {
    Fuga(FugaArgs),
}

#[derive(Debug, Args)]
struct FugaArgs {
    #[command(subcommand)]
    command: FugaCommands,
}

#[derive(Debug, Subcommand)]
enum FugaCommands {
    Piyo,
}

fn main() {
    let args = Cli::parse();

    match args.command {
        HogeCommands::Fuga(fuga_args) => match fuga_args.command {
            FugaCommands::Piyo => {
                println!("piyo");
            }
        },
    }
}

helpコマンドを実行してみる

./target/debug/hoge
Usage: hoge <COMMAND>

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

Options:
  -h, --help  Print help
./target/debug/hoge fuga
Usage: hoge fuga <COMMAND>

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

Options:
  -h, --help  Print help
./target/debug/hoge fuga piyo --help
Usage: hoge fuga piyo

Options:
  -h, --help  Print help