-
-
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
Tracking PR Custom Derive (#146) #835
Conversation
Those all sound good to me. I just tried Actually, I guess
Yeah, I was thinking of creating some nice, pretty, fake history for this 😆 there's definitely some internal stuff that needs to be designed properly before doing that (looking at it again I really dislike the code parsing the attributes, there must be a cleaner way to do it). |
I like this a lot because it allows using the standard
No worries! This can be done last. In all honesty, so long as the relevant commits get picked up by clog in order to add the changelog I'm good 😉 |
Made those changes and also
I'm tempted to actually just merge those two traits back together. I was having lifetime issues with the constraints on the |
I've put in a PR with some very minor changes. I'm just starting to dig into the code, so I expect we'll both be making changes for a little bit and additions/deletions, so I view the code as living for the time being 😄 Once we start to knock off some of these todos and we can clean up the commits and ensure everyhing is properly exported/visible. I also don't expect doc comments until we're settled on the implementation so don't worry about those yet unless something gets finalized. |
Minor changes and rustfmt
I've been thinking about the attributes parsing a bit, it should be possible to create a macro based crate (probably macros 1.1 for extra metaness) to actually parse them, which will make using the values much nicer. It will probably also make updating them as the design changes a lot easier. I threw together a I think I could probably get a working derive crate for attributes up tomorrow and switch clap-macros over to it. |
Took a little longer than I thought, but I've got a near production ready attribute parser up (https://github.com/Nemo157/prom-attire-rs) and opened a PR for switching |
Hi, StructOpt author here. First, I must say that there is high quality code and features in this PR. In fact, I feel quite depressed to see that my idea and implementation is present here with much more features and better error handling. After reading all the related issues and lightly read this PR, I just have a few remarks:
If you have any remarks or thing I can do to help, just talk! ;-) |
@TeXitoi Thanks for the comments! I agree this is a much wanted feature and something we need to look at merging soon. I'm good with merging something early under the My only concern with having something like To be clear, I'm more concerned with deriving the Here's what I mean by the two and how I imagine them working. Literally, this is my only requirements and once a PR reaches this state I'll be happy with a merge. ArgMatches->MyArgsUser code: enum VerbLevel {
Off,
Some,
All
}
#[derive(FromArgMatches)]
struct MyArgs {
verb_lvl: VerbLevel,
files: Vec<PathBuf>,
debug: bool
}
fn main() {
let args: MyArgs = App::new("myprog")
// ..snip
.get_matches()
.into();
println!("Debug turned on?: {:?}", args.debug);
} Subcommands can complicate this. But here's how Imagine those working: enum VerbLevel {
Off,
Some,
All
}
#[derive(FromArgMatches)]
struct MyArgs {
verb_lvl: VerbLevel,
files: Vec<PathBuf>,
debug: bool,
cmd: MySubCommands
}
#[derive(SubCommands)]
enum MySubCommands {
Test(Test),
Stuff(Stuff)
}
#[derive(FromArgMatches)]
struct Test {
val: String
}
#[derive(FromArgMatches)]
struct Stuff {
config: Option<String>
}
fn main() {
let args: MyArgs = App::new("myprog")
// ..snip
.get_matches()
.into();
println!("Debug turned on?: {:?}", args.debug);
match args.cmd {
Test(t) => println!("val: {}", t.val),
Stuff(s) => println("Config: {:?}", s.config),
}
} MyArgs->App/// Some text that goes into App::about
#[derive(App)]
struct MyArgs {
/// Some text that goes into Arg::help
#[clap(long = "verb", short = "v", takes_value=true, default_value="Off")]
verb_lvl: VerbLevel,
/// Some text describing --files <path>...
#[clap(long="files", takes_value=true, required=true, multiple=true)]
files: Vec<PathBuf>,
}
fn main() {
let args: App = MyArgs::into()
.get_matches();
} Again, this may be more simple than Hopefully that clears some things up.
Yes, but it shouldn't panic. Meaning, if it panics, there was a developer error and the program can't run anyways. In which case I think it should panic. I can't imagine a case where failing to parse should be allowed, or is desired. IMO it's perfectly acceptable, and even within the Rust guidelines, to panic due to developer error or when the program shouldn't be allowed to run further, which I view as this case.
I 100% agree! 👍 And I'm OK with To be clear, if we start by simply supporting The automatic long handling, I'm less inclined to support. I don't want to do something magically unless the user requested it. This could create issues when the user doesn't want a long.
Again, I 100% agree with your comments 😄
I'll rework the TODO 😉 |
@TeXitoi Welcome 😄 I had a brief look at StructOpt when it was posted to users and I was very impressed at how much it supported with such a small codebase.
I agree, that was just an artifact of my philosophy on CLI design. It should be disabled and instead there could be the shortcut attribute
Should be pretty simple, if there is a
I had something like that as an extension trait originally, but when switching to implementing
I can't either, but I could definitely see it happening in the future. One way to future-proof it would be to implement I also have some thoughts on the overall crate/code structure after setting up tests on |
I absolutely agree. But this is also something that can be added post initial merge too, so long as we think about it during the design. |
The main change to the crate structure I think is useful is to divide This division makes it possible to test error cases, you can write tests in Positive test cases can be put into the
|
In addition, I may want to consider moving all the user facing macros to Edit: in otherwords, I like the |
I don't think a proc-macro crate can export macro_rules macros. But it could have non-derive proc-macros once they're stabilised. |
Ah ok, no worries. |
This is the tracking PR for Custom Derive discussed in #146
This initial PR should cover
ArgMatches->MyArgs
conversion and potentiallyMyArgs->App
conversion. If one is holding back the other, let's move it to another PR and merge.Currently Outstanding Discussion Points / Questions
TryFromArgMatches
be implied byFromArgMatches
?Todo from previous discussion points
DefineX
toX
in traits (DefineApp
->App
)code_gen
module (stomp
->code_gen
)#[derive(FromArgMatches)]
actually generateFrom<ArgMatches>
Misc.
get_matches
variants (get_matches_from
, etc.)App
andArg
methodsunstable
clap feature (will be used until Rust 1.17 ships stable, to maintain Stable-2 compatibility)clog
conventions (can be done last)To Do
Derive FromArgMatches
#[derive(FromArgMatches)]
Default
where possible and document such)Derive App
#[derive(App)]
Derive Subcommands
#[derive(SubCommands)]
This change is