1 module python.wrap.wrap; 2 3 /// For a nicer API 4 struct Module { 5 string name; 6 } 7 8 9 /// For a nicer API 10 struct CFunctions(functions...) { 11 alias symbols = functions; 12 enum length = functions.length; 13 14 static string stringifySymbols() { 15 import std.array: join; 16 17 string[] ret; 18 19 static foreach(cfunction; symbols) 20 ret ~= __traits(identifier, cfunction); 21 22 return ret.join(", "); 23 } 24 } 25 26 /// A list of aggregates to wrap 27 struct Aggregates(T...) { 28 alias Types = T; 29 30 static string stringifyTypes() { 31 import std.array: join; 32 string[] ret; 33 34 static foreach(T; Types) 35 ret ~= T.stringof; 36 37 return ret.join(", "); 38 } 39 } 40 41 42 /** 43 A string mixin to reduce boilerplate when creating a Python module. 44 Takes a module name and a variadic list of C functions to make 45 available. 46 */ 47 string createModuleMixin(Module module_, alias cfunctions, alias aggregates)() 48 if(isPython3) 49 { 50 import std.format: format; 51 52 enum ret = q{ 53 // This is declared as an extern C variable in python.bindings. 54 // We declare it here to avoid linker errors. 55 export __gshared extern(C) PyDateTime_CAPI* PyDateTimeAPI; 56 57 import python: ModuleInitRet; 58 59 extern(C) export ModuleInitRet PyInit_%s() { 60 import python: pyDateTimeImport; 61 pyDateTimeImport; 62 return createModule!( 63 Module("%s"), 64 CFunctions!( 65 %s 66 ), 67 Aggregates!( 68 %s 69 ) 70 ); 71 } 72 }.format(module_.name, module_.name, cfunctions.stringifySymbols, aggregates.stringifyTypes); 73 74 return ret; 75 } 76 77 string createModuleMixin(Module module_, alias cfunctions, alias aggregates)() 78 if(isPython2) 79 { 80 import std.format: format; 81 82 enum ret = q{ 83 // This is declared as an extern C variable in python.bindings. 84 // We declare it here to avoid linker errors. 85 export __gshared extern(C) PyDateTime_CAPI* PyDateTimeAPI; 86 87 extern(C) export void init%s() { 88 import python: pyDateTimeImport, initModule; 89 pyDateTimeImport; 90 initModule!( 91 Module("%s"), 92 CFunctions!( 93 %s 94 ), 95 Aggregates!( 96 %s 97 ), 98 ); 99 } 100 }.format(module_.name, module_.name, cfunctions.stringifySymbols, aggregates.stringifyTypes); 101 102 return ret; 103 }