murarth / gumdrop

Rust option parser with custom derive support

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why I can't describe `free` arguments?

tailhook opened this issue · comments

Structure is:

#[derive(Options, Debug, Default)]
#[options(no_short)]
struct MyOptions {
    #[options(help="Print help message and exit")]
    help: bool,
    #[options(free, help="filename")]
    filenames: Vec<String>,
}

Error is:

  = help: message: `free` and `help` are mutually exclusive

What's wrong with describing positional arguments? Use case is kinda like in ls command. Maybe there is other way to implement positional arguments instead of free? (which is a weird name for the task indeed).

Free arguments (as they're called in getopts) don't appear in the gumdrop-generated help text. That's why they can't have a help field.

Trying to have a generic way of applying help text to free arguments would be tricky, as different programs may treat them differently. Some programs expect an arbitrary number of arguments, which are all treated the same (e.g. Unix cat utility); while others may treat arguments in the sequence differently (e.g. Unix mv, which expects source and destination arguments).

Therefore, the best option in this case appears to be allowing the user to write help text for free arguments. Something like this, perhaps:

println!("{} [OPTIONS] [FOO] [BAR]", args[0]);
println!();
println!("Non-option arguments:");
println!("  foo  Path to foo");
println!("  bar  Path to bar");
println!();
println!("{}", MyOpts::usage());

Can't I define them as the following?

struct Options {
  #[options(free)]
  foo: String,
  #[options(free)]
  bar: String,
}

I mean argparse both original python one and rust crate manage help and number of positional arguments well enough, in my opinion. I don't see any reason to rely on ancient getopt-style handling.

Hm. Individual free fields seems like a good alternative. I'll see what I can do.

Okay, I've just pushed a commit that allows multiple free fields, allows help for those fields, and displays free fields and help text in generated usage strings.

And it even preserves existing behavior (other than modified usage string), as the final (or only) free field can be Vec<T> and collect all free arguments. Everybody wins! :D

I think this issue has been resolved now. If not, feel free to correct me.