1 /**
2  * This generative method creates a getopt call based on the
3  * attributes assign to  a structure.
4  *
5  * ```
6 import structopt;
7 
8 // Specify The Parameter Structure
9 struct Options
10 {
11     @Option("threads", "t")
12     @Help("Number of threads to use.")
13     size_t threads;
14 
15     @Option("file")
16     @Help("Input files")
17     string[] files;
18 }
19 
20 void main(string[] args) {
21     Options props;
22 
23     // Pass in the struct to generate UDA for
24     auto helpInfo = mixin(GenerateGetopt!(props, args));
25 
26         defaultGetoptPrinter("Options: ",
27           helpInfo.options);
28         // Output to console:
29 
30         //Options:
31         //-t --threads Number of threads to use.
32         //      --file Input files
33         //-h    --help This help information./
34 }
35  * ```
36  */
37 module structopt;
38 
39 public import structopt.attributes;
40 public import std.getopt;
41 public import std.traits;
42 
43 /// Rename the Option struct of getopt
44 alias GetOption = std.getopt.Option;
45 /// Reastablish the name for the struct attributes
46 alias Option = structopt.attributes.Option;
47 
48 /**
49  * Generate the std.getopt method call.
50  */
51 string GenerateGetopt(alias Options, alias args)() pure nothrow {
52     import std.meta;
53     import std.typecons;
54     import std.format;
55     import std.conv;
56     auto ans = text("getopt(", args.stringof, ", ");
57     static foreach(opt; FieldNameTuple!(typeof(Options))) {
58         ans ~= text("getUDAs!(", Options.stringof, ".", opt, ", ");
59         ans ~= text(Option.stringof, ")", "[0].cononical(),");
60         ans ~= text(" getUDAs!(", Options.stringof, ".", opt, ", ");
61         ans ~= text(Help.stringof, ")[0].msg,");
62         ans ~= text(" &", Options.stringof, ".", opt, ",");
63     }
64 
65     return ans ~ ")";
66 }
67 ///
68 unittest {
69     // Specify The Parameter Structure
70     struct Options
71     {
72         @Option("threads", "t")
73         @Help("Number of threads to use.")
74         size_t threads;
75 
76         @Option("file")
77         @Help("Input files")
78         string[] files;
79     }
80 
81     Options props;
82     string[] arg = ["./structopt", "t", "24"];
83 
84     // Pass in the struct to generate UDA for
85     auto helpInfo = mixin(GenerateGetopt!(props, arg));
86     auto expected = [
87         GetOption("-t", "--threads", "Number of threads to use.", false),
88         GetOption("", "--file", "Input files", false),
89         GetOption("-h", "--help", "This help information.", false)
90     ];
91 
92     import std.algorithm;
93     assert(helpInfo.options.equal(expected));
94 
95 }