argparse version 0.7.0 - a CLI parsing library
H. S. Teoh
hsteoh at quickfur.ath.cx
Thu Mar 17 19:07:28 UTC 2022
On Mon, Mar 14, 2022 at 03:06:44AM +0000, Andrey Zherikov via Digitalmars-d-announce wrote:
> Hi everyone,
>
> I'd like to share that I've published a new version of
> [argparse](https://code.dlang.org/packages/argparse) library. It's
> got some new features since my [first
> announcement](https://forum.dlang.org/post/zjljbdzfrtcxfiuzozty@forum.dlang.org)
> as well as some bug fixes:
> - Support of the usage without UDAs
> - Custom grouping of arguments on help screen
> - Mutually exclusive arguments
> - Mutually dependent arguments
> - Subcommands
[...]
Very comprehensive library! Quite similar in concept to my own argument
parsing module that also uses a struct + UDAs for specifying options.
(Though your module is more advanced; mine doesn't handle things like
subcommands.)
I notice that some of your UDAs are pretty complicated, which makes me
wonder if you're aware that it's possible to attach multiple UDAs to a
single declaration. For example, in my own argument parsing module, I
have a UDA @Alt for specifying an alternative name (usually a
single-character shorthand) to an option, as well as a UDA @Help for
attaching help text to an option. Here's an example of both being used
for the same declaration:
struct Options {
@Alt("n") // accept `-n` in addition to `--name`
@Help("Name of the object to generate")
string name;
}
Using independent, orthogonal UDAs may make option specification using
your module easier to read. For example, from your docs:
struct T {
@(NamedArgument
.PreValidation!((string s) { return s.length > 1 && s[0] == '!'; })
.Parse !((string s) { return s[1]; })
.Validation !((char v) { return v >= '0' && v <= '9'; })
.Action !((ref int a, char v) { a = v - '0'; })
)
int a;
}
could be rewritten with multiple UDAs as:
struct T {
@NamedArgument
@PreValidation!((string s) { return s.length > 1 && s[0] == '!'; })
@Parse !((string s) { return s[1]; })
@Validation !((char v) { return v >= '0' && v <= '9'; })
@Action!((ref int a, char v) { a = v - '0'; })
int a;
}
It might also simplify your implementation by having more smaller,
independent pieces for each UDA instead of a single complex UDA that
handles everything.
Also, some of your function literals could use shorthand syntax, e.g.:
.PreValidation!((string s) { return s.length > 1 && s[0] == '!'; })
could be written as:
.PreValidation!(s => s.length > 1 && s[0] == '!')
T
--
Tell me and I forget. Teach me and I remember. Involve me and I understand. -- Benjamin Franklin
More information about the Digitalmars-d-announce
mailing list