1 /**
2    Wrapper structs to ensure type-safety and readability, as well
3    as helper types to use as arguments to build commands.
4  */
5 module reggae.types;
6 
7 import reggae.rules.common: exeExt;
8 import std.path: baseName, stripExtension, defaultExtension;
9 
10 @safe:
11 
12 struct SourceFileName {
13     string value;
14 }
15 
16 struct BinaryFileName {
17     string value;
18 }
19 
20 struct App {
21     SourceFileName srcFileName;
22     BinaryFileName exeFileName;
23 
24     this(SourceFileName srcFileName) pure {
25         immutable stripped = srcFileName.value.baseName.stripExtension;
26         immutable exeFileName = BinaryFileName(exeExt == "" ? stripped : stripped.defaultExtension(exeExt));
27 
28         this(srcFileName, exeFileName);
29     }
30 
31     this(SourceFileName srcFileName, BinaryFileName exeFileName) @safe pure nothrow {
32         this.srcFileName = srcFileName;
33         this.exeFileName = exeFileName;
34     }
35 }
36 
37 
38 struct Flags {
39     string[] value;
40 
41     this(string value) @trusted pure {
42         import std.array: split;
43         this.value = value.split;
44     }
45 
46     this(inout(string)[] values) inout @safe @nogc pure nothrow {
47         this.value = values;
48     }
49 }
50 
51 struct CompilerFlags {
52     string[] value;
53 
54     this(string value) @trusted pure {
55         import std.array: split;
56         this.value = value.split;
57     }
58 
59     this(string[] values...) @safe pure nothrow {
60         this.value = values.dup;
61     }
62 
63     this(inout(string)[] values) inout @safe @nogc pure nothrow {
64         this.value = values;
65     }
66 }
67 
68 struct LinkerFlags {
69     string[] value;
70 
71     this(string value) @trusted pure {
72         import std.array: split;
73         this.value = value.split;
74     }
75 
76     this(string[] values...) @safe pure nothrow {
77         this.value = values.dup;
78     }
79 
80     this(inout(string)[] values) inout @safe @nogc pure nothrow {
81         this.value = values;
82     }
83 }
84 
85 struct ImportPaths {
86     string[] value;
87 
88     this(inout(string)[] value) inout pure {
89         this.value = value;
90     }
91 
92     this(inout(string) value) inout pure {
93         this([value]);
94     }
95 
96 }
97 
98 alias IncludePaths = ImportPaths;
99 
100 struct StringImportPaths {
101     string[] value;
102 
103     this(inout(string)[] value) inout pure {
104         this.value = value;
105     }
106 
107     this(inout(string) value) inout pure {
108         this([value]);
109     }
110 
111 }
112 
113 struct SrcDirs {
114     string[] value;
115 
116     this(inout(string)[] value) inout pure {
117         this.value = value;
118     }
119 
120     this(inout(string) value) inout pure {
121         this([value]);
122     }
123 
124 }
125 
126 struct SrcFiles {
127     string[] value;
128 
129     this(inout(string)[] value) inout pure {
130         this.value = value;
131     }
132 
133     this(inout(string) value) inout pure {
134         this([value]);
135     }
136 
137 }
138 
139 struct ExcludeFiles {
140     string[] value;
141 
142     this(inout(string)[] value) inout pure {
143         this.value = value;
144     }
145 
146     this(inout(string) value) inout pure {
147         this([value]);
148     }
149 
150 }
151 
152 struct ExeName {
153     string value;
154 }
155 
156 struct TargetName {
157     string value;
158 }
159 
160 
161 struct Configuration {
162     string value = "default";
163 }
164 
165 enum Backend {
166     none,
167     make,
168     ninja,
169     tup,
170     binary,
171 }
172 
173 
174 struct Dirs {
175     string[] value = ["."];
176 
177     this(inout(string)[] value) inout pure {
178         this.value = value;
179     }
180 
181     this(inout(string) value) inout pure {
182         this([value]);
183     }
184 }
185 
186 struct Files {
187     string[] value;
188 
189     this(inout(string)[] value) inout pure {
190         this.value = value;
191     }
192 
193     this(inout(string) value) inout pure {
194         this([value]);
195     }
196 }
197 
198 struct Filter(alias F) {
199     alias func = F;
200 }
201 
202 struct SourcesImpl(alias F) {
203     Dirs dirs;
204     Files files;
205     Filter!F filter;
206 
207     alias filterFunc = F;
208 }
209 
210 auto Sources(Dirs dirs = Dirs(), Files files = Files(), F = Filter!(a => true))() {
211     return SourcesImpl!(F.func)(dirs, files);
212 }
213 
214 auto Sources(string[] dirs, Files files = Files(), F = Filter!(a => true))() {
215     return Sources!(Dirs(dirs), files, F)();
216 }
217 
218 auto Sources(string dir, Files files = Files(), F = Filter!(a => true))() {
219     return Sources!([dir], files, F)();
220 }
221 
222 struct SourceFile {
223     string value;
224 }
225 
226 
227 struct ProjectDir {
228     string value = "$project";
229 }