Clap: `clap_app!` can't have default arguments with numbers/some characters.

Created on 21 Aug 2017  路  6Comments  路  Source: clap-rs/clap

Rust Version

rustc 1.21.0-nightly (8c303ed87 2017-08-20)

Affected Version of clap

2.26.0

Expected Behavior Summary

The clap_app! macro can have arguments with defaults which are numbers or contain special characters, possibly with some quoting.

Actual Behavior Summary

No amount of quoting can stop Clap from failing to parse the macro form properly.

Steps to Reproduce the issue

Try to compile the sample code. Replace the default arguments with simple strings and see it compile successfully.

Sample Code or Link to Sample Code

#[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();
}

Debug output

No output.

builder macros medium bug 3.x

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:

#[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.

All 6 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BurntSushi picture BurntSushi  路  5Comments

milgner picture milgner  路  5Comments

sharkdp picture sharkdp  路  5Comments

AdamNiederer picture AdamNiederer  路  3Comments

jsgf picture jsgf  路  5Comments