clap
clap copied to clipboard
Question - how can I print the arguments given an opt instance?
Issue by avnerbarr
Thursday Oct 15, 2020 at 13:51 GMT
Originally opened as https://github.com/TeXitoi/structopt/issues/441
I want to get the string representation leading to a particular Opt instance (after I've modified it).
for instance
#[derive(StructOpt)]
struct Opt {
a : String,
b: String,
c: i32,
...
z : String
}
...
let opts = Opt::from_args();
...
if some condition occured, change opts and print the correct representation {
let new_opts = Opt { z: "this_value_should_be_written", ..Opt::from_args() }; // change some values
print(how do I print "new_opts" in such a way that is valid for the Opt parser for next run?)
}
Comment by EverlastingBugstopper
Monday Oct 19, 2020 at 18:05 GMT
you could add a debug derivation like so: #[derive(StructOpt, Debug)]
and then print like println!("{:?}, new_opts);
or even println!("{:#?}", new_opts);
Comment by TeXitoi
Tuesday Oct 20, 2020 at 09:16 GMT
AFAIK, that's not possible, and it will be a quite complicated feature, relying deeply in clap internal.
Comment by therealbnut
Tuesday Apr 06, 2021 at 00:32 GMT
Adding to this I want to use structopt
for IPC with a forked child process, and so I'd like to be able to go from an Opt
structure to a Vec
/Iterator
of argument strings.
ie.
enum Opt {
#[structopt(short, long)]
host_name: String,
}
// ["--host_name", "my-server"]
(Opt { host_name: "my-server".to_owned() }).args()
If this was possible then you could emit debugging info by doing:
println!("{:?}", op.args())
Comment by Xaeroxe
Monday Oct 04, 2021 at 16:29 GMT
@TeXitoi would you be open to a PR implementing this?
@epage This is currently possible with v3, right?
I'm not aware of a way to convert a Parser
to a valid args.
First, doing so would only work if all fields are Display
(which will fail in common cases like Path
). Ideally we would be instead generating OsStrings
rather than Strings
and there isn't anything like Display
for OsStr
though we could generate some specialization hacks to work in some cases.
Second, we'd have to examine all of the attributes to see what a valid command would look like.
- The most obvious is dealing with if a short/long is needed and what that is.
- An example of an easy to miss case is if they set
require_equals
. - A complicated case is when it comes to validation rules and defaulting. Once #3020 goes in, users can set requires that ignore defaults but we will have a hard time knowing in this what is a default to not put in the command line.
Of course, with all features, there is a question of how much correctness is needed so you aren't laying traps for people vs how much it gets in the way of progress.
The shape I'd like to see this API take would be
-
clap
exposes an additional derive trait, called something likeIntoArgs
(we can bikeshed the name) - That trait provides a method for generating an
Iterator
ofOsString
s. - That
Iterator
can be fed intostd::process::Command::args
and if the target executable usesParser::parse()
on the same structure definition that we usedIntoArgs
on, then the transmission of the structure between programs is guaranteed to be correct.*
* Barring further manipulation of the Command
which may invalidate the argument structure and ordering
It may be possible to lean on the serde data model for this. i.e. if the structure also implements serde::Serialize
then clap
only has to accept the serde data model, rather than requiring all of the members to implement some new trait that reverses FromStr
. Display
would be a poor choice for reversing FromStr
because Display
doesn't require a guarantee that it's compatible with FromStr
. However it's worth noting that using the serde data model has a similar problem, unless clap
also starts using serde
for deserializing the arguments.
Is it generally possible to generate a correct std::process::Command
regardless of the OS, or is this complicated enough that Clap would have to target another library?
"Regardless of OS" part is likely the easy part. The hard part is more in getting the data back out once it has been parsed as I outlined above.