How to Use clap and config Together for CLI Configuration

Combine clap and config by deriving Parser and Deserialize on a single struct to merge CLI args and config files automatically.

Use clap to parse command-line arguments and config to load a configuration file, then merge them into a single struct using serde. Define a struct with #[derive(Parser, Deserialize)], add #[command(flatten)] to the config field, and parse the CLI first to allow overrides.

use clap::Parser;
use serde::Deserialize;

#[derive(Parser, Deserialize)]
struct Config {
    #[arg(short, long)]
    query: String,
    #[arg(short, long, default_value = "src/main.rs")]
    file_path: String,
}

fn main() {
    let config = Config::parse();
    println!("Query: {}, File: {}", config.query, config.file_path);
}
  1. Add clap = { version = "4", features = ["derive"] } and serde = { version = "1", features = ["derive"] } to Cargo.toml.
  2. Define a struct with #[derive(Parser, Deserialize)] and annotate fields with #[arg(...)] for CLI flags and #[serde(...)] for config file keys.
  3. Call Config::parse() in main() to automatically merge environment variables, config files, and CLI arguments, with CLI taking precedence.