1 /**
2    Types to be used in the API for type-safety
3    (as opposed to, say, raw strings).
4  */
5 module autowrap.types;
6 
7 
8 template isModule(alias T) {
9     import std.traits: Unqual;
10     static if(is(T))
11         enum isModule = is(Unqual!T == Module);
12     else
13         enum isModule = is(Unqual!(typeof(T)) == Module);
14 }
15 
16 
17 /**
18    The list of modules to automatically wrap for consumption by other languages.
19  */
20 struct Modules {
21     import std.traits: Unqual;
22     import std.meta: allSatisfy;
23     import std.typecons: Flag;
24 
25     private enum isString(T) = is(Unqual!(T) == string);
26     private enum isModuleOrString(T) = isModule!T || isString!T;
27 
28     Module[] value;
29 
30     this(A...)(auto ref A modules) if(allSatisfy!(isModuleOrString, A)) {
31 
32         foreach(module_; modules) {
33             static if(is(Unqual!(typeof(module_)) == Module))
34                 value ~= module_;
35             else static if(is(Unqual!(typeof(module_)) == string))
36                 value ~= Module(module_);
37             else
38                 static assert(false, "Modules must either be `string` or `Module`");
39         }
40     }
41 
42     this(A...)(Flag!"alwaysExport" alwaysExport, A moduleNames) if(allSatisfy!(isString, A)) {
43         static foreach(moduleName; moduleNames) {
44             value ~= Module(moduleName, alwaysExport);
45         }
46     }
47 }
48 
49 /**
50    A module to automatically wrap.
51    Usually not needed since a string will do, but is useful when trying to export
52    all functions from a module by using Module("mymodule", Yes.alwaysExport)
53    instead of "mymodule"
54  */
55 struct Module {
56     import std.typecons: Flag, No;
57 
58     string name;
59     Flag!"alwaysExport" alwaysExport = No.alwaysExport;
60     Ignore[] ignoredSymbols;
61 
62     this(string name) {
63         this(name, No.alwaysExport);
64     }
65 
66     this(string name, Flag!"alwaysExport" alwaysExport, Ignore[] ignoredSymbols...) {
67         this.name = name;
68         this.alwaysExport = alwaysExport;
69         this.ignoredSymbols = ignoredSymbols;
70     }
71 
72     string toString() @safe pure const {
73         import std.conv: text;
74         import std..string: capitalize;
75         return text(`Module("`, name, `", `, text(alwaysExport).capitalize, `.alwaysExport, `, ignoredSymbols, `)`);
76     }
77 }
78 
79 
80 /**
81    Used in a module to ignore certain symbols
82  */
83 struct Ignore {
84     string identifier;
85 }
86 
87 /**
88    The name of the dynamic library, i.e. the file name with the .so/.dll extension
89  */
90 struct LibraryName {
91     string value;
92 }
93 
94 /**
95    Code to be inserted before the call to module_init
96  */
97 struct PreModuleInitCode {
98     string value;
99 }
100 
101 /**
102    Code to be inserted after the call to module_init
103  */
104 struct PostModuleInitCode {
105     string value;
106 }
107 
108 
109 struct RootNamespace {
110     string value;
111 }
112 
113 struct OutputFileName {
114     string value;
115 }