-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 #3117
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 😃 |
@qmx Um, I'm not the guy in charge here, you should be asking @TeXitoi. Personally, I have no objection |
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? |
Unfortunately, I do not see this technical limitation going away. We have limited communication when flattening and any of that communication will be at runtime, not compile time, ie we would have to do string formatting and leak the result. |
@epage WDYT of an |
To allow an
The biggest challenge is with "Uniquification of |
For reference I proposed here #4556 (comment) that we allow prefix in the |
Does anyone know a good workaround for this? Currently I'm contemplating taking a shared struct with If you see a simpler way I'm interested to hear about it |
Sunday Jun 03, 2018 at 22:03 GMT
Originally opened as TeXitoi/structopt#114
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: