Skip to content
← Dist
rustcli.rsrustclapcli

Clap nested subcommands

Minimal clap derive CLI with a top-level command and nested subcommands.

clap 4 derive style — one binary, nested app db … commands. Add real work inside each match arm.

use clap::{Parser, Subcommand};

#[derive(Parser, Debug)]
#[command(name = "slap", version, about = "Tiny nested-command demo")]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand, Debug)]
enum Commands {
    /// Application helpers
    App {
        #[command(subcommand)]
        action: AppCmd,
    },
    /// Database helpers
    Db {
        #[command(subcommand)]
        action: DbCmd,
    },
}

#[derive(Subcommand, Debug)]
enum AppCmd {
    /// Print status
    Status,
    /// Warm caches
    Warm { #[arg(long, default_value = "local")] env: String },
}

#[derive(Subcommand, Debug)]
enum DbCmd {
    Migrate,
    Seed { #[arg(long)] force: bool },
}

fn main() {
    let cli = Cli::parse();
    match cli.command {
        Commands::App { action } => match action {
            AppCmd::Status => println!("app: ok"),
            AppCmd::Warm { env } => println!("warming caches for {env}"),
        },
        Commands::Db { action } => match action {
            DbCmd::Migrate => println!("running migrations"),
            DbCmd::Seed { force } => {
                println!("seeding (force={force})");
            }
        },
    }
}