confusing failure mode when usage and option sections are inconsistent
When the following test program is executed with --output out --input in arguments, the values switch places, the input variable in Args gets "out" and the output one gets the "in" value.
I encountered this issue with 0.8.1 and the latest nightly (rustc 1.21.0-nightly).
Test program
extern crate docopt;
#[macro_use]
extern crate serde_derive;
use docopt::Docopt;
const USAGE: &'static str = "
Usage:
xxxx [--input <input>] [--output <output>]
xxxx --help
Options:
-i, --input Input file
-o, --output Output file
-h, --help Display this message
";
#[derive(Debug, Deserialize)]
struct Args {
arg_input: Option<String>,
arg_output: Option<String>,
}
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit());
println!("{:?}", args);
}
Result
Args { arg_input: Some("out"), arg_output: Some("in") }
Expected result
Args { arg_input: Some("in"), arg_output: Some("out") }
I don't think there's any bug here, but the failure mode is obviously bad.
There are two errors in your example code. Firstly, your option description section needs to indicate that a flag takes an argument. So instead of -i, --input, you'd write -i, --input <input>. Secondly, your members in your Args struct have an arg prefix, but they are flags, which means they need a flag prefix. arg is for positional arguments. This behavior is documented on the ArgvMap::deserialize method.
Ideas on how to improve the failure modes here would be appreciated. It seems like the least we could do is report the inconsistency between the flag definition --input <input> in the USAGE section and the inconsistent -i, --input definition in the option description section.
Oh, sorry for mixing these things up in the example. I just assumed something's wrong with the crate because it acted weird in this case and didn't throw errors at me (like it does for the missing args).