Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argument order resulting in: "invalid digit found in string" #430

Closed
bernardoamc opened this issue Sep 14, 2020 · 2 comments
Closed

Argument order resulting in: "invalid digit found in string" #430

bernardoamc opened this issue Sep 14, 2020 · 2 comments

Comments

@bernardoamc
Copy link

First thank you for structopt, it's such a great piece of software. :)

I'm not sure if what I've encountered is a bug or expected behaviour, but I would love to hear if there are alternatives where I can accept a single value regardless of order for my argument. This situation can be best explained with the following examples:

Problematic input order

$ cargo run -- -b 1 --p 80 127.0.0.1
error: Invalid value for '--ports <ports>...': invalid digit found in string

Working alternatives

$ cargo run -- -b 1 -p 80, 127.0.0.1
// OR
$ cargo run --  -p 80 -b 1 127.0.0.1

I'm not sure if I have the wrong mental model and it's expected that this wouldn't work with FromStr.

Minimum setup in order to replicate:

pub struct Opts {
    #[structopt(use_delimiter = true)]
    pub addresses: Vec<String>,

    #[structopt(short, long, use_delimiter = true)]
    pub ports: Option<Vec<u16>>,

    #[structopt(short, long, default_value = "4500")]
    pub batch_size: u16,
}
@CreepySkeleton
Copy link
Collaborator

Nit: I think you're confusing --p with -p in the first example.

Anyway, the problem here is that clap first parses the args according to the spec, and only then tries to validate them. You're expecting that -p 80 127.0.0.1 is parsed as <option> <value> <FromStr failed, stop here>, but it's parsed as <option> <value1> <value2, validation will fail>. Basically, there's no way to say "this option takes multiple values, but only as long as the validator passes". See clap-rs/clap#2122

We can't do anything about it in structopt. As a workaround, I suggest you to redesign your CLI:

  • Make -p take only one value, but allow it to occur more than once:
    #[structopt(short, long, use_delimiter = true, number_of_values = 1)]
    pub ports: Vec<u16>,
    cargo run -- -b 1 -p 80 -p 22 127.0.0.1
    
  • Make address an option instead of positional argument.

@bernardoamc
Copy link
Author

I see, thank you for the insight @CreepySkeleton! Thinking in retrospect it makes a lot of sense.

Multiple -p are not an option due to the sheer amount of ports, but making address an option might be possible. Worst case scenario I might take the custom parser route and do the validation myself for this argument. Thank you so much for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants