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