I have a CLI implemented using structopt. I would like to have an optional flag which defaults to some value that can be overridden, or switched off completely. For example
prog # x = Some(3)
prog -x 4 # x = Some(4)
prog -x no # x = None
This hopefully illustrates that
x = 3 by default
the default can be overridden
the option can be switched off
The use of no as the switch-off token, is just an example: any convenient to type marker would do.
Can you suggest a clean way of implementing this in structopt?
You can use a custom parse function for this. You'll also need to spell the field's type as something other than just Option<T>, to disable structopt's default handling of that type:
use std::num::ParseIntError;
use structopt::StructOpt;
// alias to disable structopt's type magic
type MyOption<T> = Option<T>;
#[derive(Debug, StructOpt)]
struct Opt {
#[structopt(
short = "x",
default_value = "3",
parse(try_from_str = number_or_no))]
x: MyOption<i32>,
}
fn number_or_no(s: &str) -> Result<MyOption<i32>, ParseIntError> {
let val = if s == "no" { None } else { Some(s.parse()?) };
Ok(val)
}
fn main() {
let opt = Opt::from_args();
println!("{:?}", opt.x);
}