Can I parse "alternative" set of parameters with clap/structopt?

I am trying to use structopt/clap to parse the arguments of a CLI which supports the two following invocations:

# Accept a single file and a list of labels
$ my_cli FILE LABEL...
# Accept a list of files
$ my_cli --labels="label1 label2" FILE ... 

With structopt, I would normally store the files in a Vec<PathBuf> and the labels in a Vec<Label>. Unfortunately, having two vectors as positional arguments is ambiguous, and Clap panics with:

When using a positional argument with .multiple(true) that is *not the last* positional argument,
the last positional argument (i.e the one with the highest index) *must* have .required(true)
or .last(true) set.

I would like to tell Clap somehow that the two Vec will never occur at the same time. Using conflicts_with() and friends does not help. I thought I could use an ArgGroup for each alternative, but this doesn't seem to work either (please let me know if I missed something here).

I suppose I could have a single Vec<String> and reuse it for both files and labels, but this would mean more manual work to convert to the proper types, and it would mess with the help message. Is there a better way to do this kind of thing?

I don't think this is possible with clap as it allows you to put named arguments anywhere in your arguments, but in order to unambiguously parse your syntax you'd have to require them (or at least --labels) to come before the positional arguments.

You could write two separate argument parsers, one with --labels and one with the positional arguments. If the first parse fails, try the second.

Thank you, I will give it a try.

I will still have to take care of the help message manually (at least partially), right?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.