-
Notifications
You must be signed in to change notification settings - Fork 9
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
ability to treat all remaining arguments as free arguments #1
Comments
I wrote up a whole reply before realizing that there is a way to do this, though it's arguably abusing the API: fn main() -> Result<(), Box<dyn std::error::Error>> {
use lexopt::prelude::*;
let mut parser = lexopt::Parser::from_env();
while let Some(arg) = parser.next()? {
match arg {
Short(ch) => println!("Got short flag -{}", ch),
Long(opt) => println!("Got long flag --{}", opt),
Value(val) => {
println!("Got free arg {:?}", val);
while let Ok(val) = parser.value() {
println!("Got free arg {:?}", val);
}
}
}
}
Ok(())
} or more cryptically but maybe more usefully: fn main() -> Result<(), Box<dyn std::error::Error>> {
use lexopt::prelude::*;
let mut parser = lexopt::Parser::from_env();
let mut free = Vec::new();
while let Some(arg) = parser.next()? {
match arg {
Short(ch) => println!("Got short flag -{}", ch),
Long(opt) => println!("Got long flag --{}", opt),
Value(val) => {
free.push(val);
free.extend(std::iter::from_fn(|| parser.value().ok()));
}
}
}
println!("Got free arguments {:?}", free);
Ok(())
}
I don't think this should get its own method but it's worth documenting somewhere. Not sure where. In |
That's awesome news. The current documentation for .value() does make it sound like it's strictly for getting a value after seeing an option, but it indeed has the ability to be more generic. It also advises against using it as a way to collect positional arguments. It might be worth rewording as: """ Get the next value from the command line. This function should normally be called right after seeing an option that expects a value. Positional arguments should be collected using next(), but this function can also be used to collect all remaining positional arguments in cases where there is a need to stop processing options. A value is collected even if it looks like an option (i.e., starts with -). |
Also, a quick API suggestion that might make .value() cleaner would be for the signature to be: pub fn value(&mut self) -> Option<OsString> With None indicating an end of command line, similar to how Iterators use None to indicate they are finished returning values. |
Yes, I think I'll do something like that. The wrinkle is that it's only 100% correct to do that right after seeing an
This would be a cleaner signature, but it would make it harder to use in the common case. Right now you can just write Some day it might be possible to have a return type of |
I wrote up an example and linked to it from Thank you for asking about this! I had wondered about it before. |
Hi, really nice library.
I would like to stop parsing options when I encounter a "free" argument (a Arg::Value) and treat all subsequent arguments as "free" arguments, regardless if they contain option flags. Ideally, I would be able to call something like parser.finish() (fn finish(self) -> Vec<OsString>) to get the remaining arguments. I didn't see an obvious way to do it with the current API.
The text was updated successfully, but these errors were encountered: