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.