4

By default, a boolean field is set to false, but I want it set to true by default.

I tried to use [default: true] in the docopt description, but it seems default cannot be applied to a boolean option. I also tried to use Rust's Default trait - it doesn't work either.

The following is a minimal example:

extern crate rustc_serialize;
extern crate docopt;

use docopt::Docopt;

const USAGE: &'static str = "
Hello World. 

Usage:
  helloworld [options]

Options:
  --an-option-with-default-true   This option should by default be true
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_an_option_with_default_true: bool,
}

impl Args {
    pub fn init(str: &str) -> Args {
        Docopt::new(USAGE)
            .and_then(|d| d.argv(str.split_whitespace().into_iter()).parse())
            .unwrap_or_else(|e| e.exit())
            .decode()
            .unwrap()
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
qinsoon
  • 1,433
  • 2
  • 15
  • 34
  • 2
    Could you explain how you would set the value to false? – J. P. Petersen Mar 15 '17 at 12:10
  • If there's no way to set it to `false`, then the problem is easily solved: `const FLAG_AN_OPTION_WITH_DEFAULT_TRUE: bool = true;` – Shepmaster Mar 15 '17 at 13:00
  • @Shepmaster Errm, the issue is that if a flag defaults to true, then there is no way for an end user to set the flag to false. Because of that, it doesn't make sense to default a flag to true. A flag is either given (true) or not (false). – BurntSushi5 Mar 15 '17 at 14:27
  • 1
    @BurntSushi5 I know, my comment was tongue-in-cheek ;-) – Shepmaster Mar 15 '17 at 14:47

2 Answers2

2

The author of the crate says it's not possible, so that's as authoritative of an answer you can get.


As an alternative, you can take an argument that defaults to "true":

const USAGE: &'static str = "
Hello World. 

Usage:
  helloworld [options]

Options:
  --an-option=<arg>   This option should by default be true [default: true].
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_an_option: String,
}

impl Args {
    // ...

    fn an_option(&self) -> bool {
        self.flag_an_option == "true"
    }
}

fn main() {
    let a = Args::init("dummy");
    println!("{}", a.an_option()); // true

    let a = Args::init("dummy --an-option=false");
    println!("{}", a.an_option()); // false

    let a = Args::init("dummy --an-option=true");
    println!("{}", a.an_option()); // true
}

Or you could have a flag that has inverse logic:

const USAGE: &'static str = "
Hello World. 

Usage:
  helloworld [options]

Options:
  --disable-an-option
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_disable_an_option: bool,
}

impl Args {
    // ... 

    fn an_option(&self) -> bool {
        !self.flag_disable_an_option
    }
}

fn main() {
    let a = Args::init("dummy");
    println!("{}", a.an_option()); // true

    let a = Args::init("dummy --disable-an-option");
    println!("{}", a.an_option()); // false
}

Remember that you can implement methods on the parsed argument struct that make it easier to deal with.

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
1

No.

Docopt itself does not provide a way to "disable" a flag, so if a flag defaulted to true---even when it's not given by an end user---then it would be impossible for that flag to ever be false.

BurntSushi5
  • 13,917
  • 7
  • 52
  • 45