rustcommand-line-interfaceclap

Setting in boolean flag in Rust CLI tool using `clap`


I am trying to have a CLI tool that redacts files in a folder according to some specified regexes.

In debugging, as an example:

cargo run -- folder ./tests/test_files -t emails ip -r

which means to redact all files in folder path = ./tests/test_files and -r means to do so recursively.

Below is a list of structs that attempted to achieve this:

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

#[derive(Debug, Parser)]
#[clap(author, version, about, name = "raf")]
pub struct Opts {
    #[clap(subcommand)]
    pub cmd: FileOrFolder,
}

#[derive(Debug, Subcommand)]
pub enum FileOrFolder {
    #[clap(name = "folder")]
    Folder(FolderOpts),
    #[clap(name = "file")]
    File(FileOpts),
}

#[derive(Args, Debug)]
pub struct FolderOpts {
    /// `path` of the directory in which all files should be redacted, e.g. ./tests/test_files
    #[clap(parse(from_os_str), required = true)]
    pub path: std::path::PathBuf,

    /// The type of redaction to be applied to the files, e.g. -t sgNRIC emails
    #[clap(short, long, required = true, multiple_values = true)]
    pub types: Vec<String>,

    #[clap(short, long, required = false, takes_value = false)]
    pub recursive: Option<bool>,
}

This is the error that occurs during runtime:

Finished dev [unoptimized + debuginfo] target(s) in 45.31s
     Running `target\debug\raf.exe folder ./tests/test_files -t sgNRIC email -r`
error: The argument '--recursive <RECURSIVE>' requires a value but none was supplied

For more information try --help
error: process didn't exit successfully: `target\debug\raf.exe folder ./tests/test_files -t sgNRIC email -r` (exit code: 2)

My question is, how do I write the struct FolderOpts such that if -r is present in as a parameter in the CLI arguments, it is parsed as .recursive = true and if it is absent, .recursive = false?


Solution

  • bool options don't need to be wrapped in Option to be optional. They are set to false by default and true if their name is passed as argument. This should work:

    #[clap(short, long)]
    pub recursive: bool,