rustc 1.21.0-nightly (8c303ed87 2017-08-20)
2.26.0
The clap_app! macro can have arguments with defaults which are numbers or contain special characters, possibly with some quoting.
No amount of quoting can stop Clap from failing to parse the macro form properly.
Try to compile the sample code. Replace the default arguments with simple strings and see it compile successfully.
#[macro_use]
extern crate clap;
fn main() {
let matches = clap_app!(app =>
(@arg host: default_value[foo.com] "hostname")
(@arg port: default_value[8080] "port number")).get_matches();
}
No output.
Thanks for reporting! I'm in the process of trying to get 3.x out the door, so I'll verify/fix this issue on that branch.
I'm not sure if the following was possible back when this issue was originally created, but I'm able to create a default argument (that's a number) like so:
#[macro_use]
extern crate clap;
fn main() {
let matches = clap_app!(app =>
(@arg host: default_value[foo.com] "hostname")
(@arg port: default_value("8080") "port number")).get_matches();
}
It's a workaround, but I hope that's helpful for others until 3.x arrives.
hello @gluxon , could you explain a bit the difference between [] and () in default_value, and also why we need to add double quote for 8080 not foo.com.
Thanks in advance!
hello @gluxon , could you explain a bit the difference between [] and () in default_value
Sure.
[] and () are both valid ways to call a function-like macro. So in terms of the Rust programming language, they're both exactly the same. For example, the first two lines are common, but all 4 are valid lines of Rust code.
println!("hello");
let a = vec![1, 2, 3];
println!["hello"];
let a = vec!(1, 2, 3);
However, one works where the other doesn't here because of quirks in how clap_app and default_value are implemented. You would have to look at the source code for those two functions to see exactly why.
and also why we need to add double quote for 8080 not foo.com.
I'm also not 100% sure, but it's for similar reasons as above. Command line arguments are parsed as strings, so the fact that it's quoted doesn't change the type, but it gets around quirks in the aforementioned macro implementations.
With the upcoming PR which would close this issue, for certain characters, you would need to wrap them in ". Otherwise, numbers will be allowed now
fn main() {
let matches = clap_app!(app =>
(@arg host: default_value["foo.com"] "hostname")
(@arg port: default_value[8080] "port number")).get_matches();
}
Um, I don't get what problem is about.
#[macro_use]
extern crate clap;
fn main() {
let matches = clap_app!(app =>
(@arg host: default_value["foo.com"] "hostname")
(@arg port: default_value["8080"] "port number")).get_matches();
}
There's no way to distinguish between "string literal" and <any other expression> on macro_rules! level so I think requiring values to be &str is a fair compromise.
Most helpful comment
I'm not sure if the following was possible back when this issue was originally created, but I'm able to create a default argument (that's a number) like so:
It's a workaround, but I hope that's helpful for others until 3.x arrives.