-
Notifications
You must be signed in to change notification settings - Fork 152
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
Idea: flatten attribute could allow setting a prefix and suffix #114
Comments
This is implemented except the prefix feature |
I hit a weird corner-case in #[macro_use]
extern crate structopt;
#[derive(Debug, StructOpt)]
struct Opts {
#[structopt(flatten)]
incoming: Incoming,
#[structopt(flatten)]
outgoing: Outgoing,
}
#[derive(Debug, StructOpt)]
struct Incoming {
#[structopt(long = "port-in")]
port: u16,
}
#[derive(Debug, StructOpt)]
struct Outgoing {
#[structopt(long = "port-out")]
port: u16,
}
fn main() {
use structopt::StructOpt;
let cli = Opts::from_args();
println!("{:#?}", cli);
}
My current workaround is to disambiguate colliding fields with unique structopt-names, e.g. #[structopt(name = "outgoing.port", long = "port-out")] /cc @steveej FYI |
I don't think the prefix thing is possible at compile time because we can't pass info between macro calls (every |
@CreepySkeleton wouldn't we be able to do this by optionally making
one thing I couldn't figure out is how would we make it work both as a sole identifier and as a method to not break current usage (without making it too ugly 😛) |
@qmx It's not about precise syntax, it's about technical complexity. The main problem is: macro calls are independent, the expansion order is not defined, there's no way to pass some info from one invocation to another. #[derive(StructOpt)] // first expansion
struct Opt {
// this is the place where we *actually* have
// the info needed
#[flatten(prefix = "foo")]
a: Foo,
}
#[derive(StructOpt)] // second expansion
struct Foo {
// this is the place where we need to *apply*
// this prefix info
#[structopt(short = "p", long = "port")]
port: u16,
} We simply cannot pass this info on compile time. The only way to implement this is to generate code that dispatches it at runtime (i.e when user's program actually executes). This is how |
The syntax looks fine to me, could you explain what it would break, exactly? |
Ooooh, now I get what you meant! Thanks for taking the time to explain it! Even if the implementation isn't that straightforward, would the project accept a PR for this functionality? Checking before I sink time trying to figure this out 😃 |
Any advancements on this issue? I'd really like to have this feature as well. |
@oberien The real blocker here (apart from the lack of inter-expansion communication in proc-macros as mentioned above) is clap's API. To implement this we would need We need them because all we have at any You might say - "Come on, those fields are But there is still a blink of light in the darkness: structopt is being imported directly into clap and, since it will be technically one repo, we could implement it with no problem. |
I agree, I prefer avoiding these kind of dirty hacks. |
Murdering a kitten is certainly rather worse than software development minutiae, but you have the point.
Or is this just until the stable |
This warning explain that the derive crate should not be used directly, but the non derive crate export the functionalities. |
For the record: this quote is from clap_derive, not from structopt. The wording is awkward though, we'll change it to something more descriptive. The meaning here is that the derive is pretty useless on it's own, without For the sake of having a place to direct future questions to, I'm giving the most comprehensive answer I can come up with to the questions I've been asked before at once:
|
It would be a very useful feature, though. In case e.g. one is connecting to two databases, one can setup a Will any future version (e.g. clap v3) be able to overcome the technical limitations? |
This is an enhancement, and structopt is now feature frozen. |
Allow something like:
The goal being to end up with something like
There's some annoying semantic stuff that might make this impossible:
default_value
? Does the type need toimpl FromStr
in such a way that it does the desired thing? Eg, in this case maybedefault_value = "ip:port"
where either part can be left out and not set a default for it. But then validation gets weird.Also unclear if there are more use cases. It fits well here, but who knows about other places!
This came up from thinking about clap-rs/clap-port-flag#2 (review).
The text was updated successfully, but these errors were encountered: