gumdrop icon indicating copy to clipboard operation
gumdrop copied to clipboard

Use Option for optional arguments

Open canadaduane opened this issue 4 years ago • 2 comments

This would potentially be a breaking API change, but I'd like to suggest that the Option type be used for optional arguments.

Currently, Option seems to be superfluous, as arguments are still optional unless the "required" meta flag is set.

In addition, the following scenario seems to be unachievable with the current implementation:

  • an optional argument that optionally accepts a value
  • has a default value when not set

As an example, let's say a command-line tool normally has output that is unsorted. If you pass the -s argument in, then output should become sorted in some default way (e.g. alphabetically). Additionally, if you pass a value to the -s argument, you can specify the way in which the sort occurs (e.g. "-sa" for alphabetical, "-sn" for numerical).

In my case, the "principal of least surprise" led me to think that the following might achieve that result:

#[derive(Debug, Options)]
struct GramsOptions {
    #[options(help = "sort tallied output: a=alphabetic [DEFAULT], n=numeric")]
    sort: Option<String>,
}

I expected I might be able to parse this as follows:

let sort: Option<Sort> = match opts.sort.as_ref().map(|s| &s[..]) {
    Some("a") => Some(Sort::Alphabetic),
    Some("n") => Some(Sort::Numeric),
    None => Some(Sort::Alphabetic),
};

canadaduane avatar Jul 25 '19 00:07 canadaduane

In addition, the following scenario seems to be unachievable with the current implementation:

  • an optional argument that optionally accepts a value
  • has a default value when not set

Not true. There are at least two ways of accomplishing this:

#[derive(Options)]
struct OptionA {
    sort: Option<String>
}

let opts = OptionA::parse_args_default_or_exit();

// Your code handling the option provides the default value
let sort = match opts.sort.as_ref().map(|s| &s[..]) {
    Some("a") => Sort::Alphabetic,
    Some("n") => Sort::Numeric,
    Some(_) => // error
    None => Sort::Alphabetic,
};

Or:

#[derive(Options)]
struct OptionB {
    #[options(default = "a")]
    sort: String,
}

let opts = OptionB::parse_args_default_or_exit();

// gumdrop provides the default value
let sort = match &opts.sort[..] {
    "a" => Sort::Alphabetic,
    "n" => Sort::Numeric,
    _ => // error
};

The OptionA example is quite similar to your provided example. In what way is this not working as expected?

murarth avatar Jul 25 '19 17:07 murarth

Just wanted to note that I haven't forgotten about this, and will reply soon.

On Thu, Jul 25, 2019 at 11:44 AM Murarth [email protected] wrote:

In addition, the following scenario seems to be unachievable with the current implementation:

  • an optional argument that optionally accepts a value
  • has a default value when not set

Not true. There are at least two ways of accomplishing this:

#[derive(Options)]struct OptionA { sort: Option<String> } let opts = OptionA::parse_args_default_or_exit(); // Your code handling the option provides the default valuelet sort = match opts.sort.as_ref().map(|s| &s[..]) { Some("a") => Sort::Alphabetic, Some("n") => Sort::Numeric, Some(_) => // error None => Sort::Alphabetic, };

Or:

#[derive(Options)]struct OptionB { #[options(default = "a")] sort: String, } let opts = OptionA::parse_args_default_or_exit(); // gumdrop provides the default valuelet sort = match &opts.sort[..] { "a" => Sort::Alphabetic, "n" => Sort::Numeric, _ => // error };

The OptionA example is quite similar to your provided example. In what way is this not working as expected?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/murarth/gumdrop/issues/22?email_source=notifications&email_token=AAAABAIFBUKOFTFIZX5QVQDQBHRBLA5CNFSM4IGVXPI2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD22HQWI#issuecomment-515143769, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAABAKAPYMLRMKIJMEZXW3QBHRBLANCNFSM4IGVXPIQ .

canadaduane avatar Jul 29 '19 16:07 canadaduane