1 /** 2 Lazy import symbols 3 */ 4 module bolts.from; 5 6 /** 7 Encompases the from import idiom in an opDispatch version 8 9 Since: 10 - 0.12.0 11 12 See_Also: 13 <li> https://dlang.org/blog/2017/02/13/a-new-import-idiom/ 14 <li> https://forum.dlang.org/thread/gdipbdsoqdywuabnpzpe@forum.dlang.org 15 */ 16 enum from = FromImpl!null(); 17 18 /// 19 unittest { 20 // Call a function 21 auto _0 = from.std.algorithm.map!"a"([1, 2, 3]); 22 // Assign an object 23 auto _1 = from.std.datetime.stopwatch.AutoStart.yes; 24 25 // compile-time constraints 26 auto length(R)(R range) if (from.std.range.isInputRange!R) { 27 return from.std.range.walkLength(range); 28 } 29 30 assert(length([1, 2]) == 2); 31 } 32 33 private template CanImport(string moduleName) { 34 enum CanImport = __traits(compiles, { mixin("import ", moduleName, ";"); }); 35 } 36 37 private template ModuleContainsSymbol(string moduleName, string symbolName) { 38 enum ModuleContainsSymbol = CanImport!moduleName && __traits(compiles, { 39 mixin("import ", moduleName, ":", symbolName, ";"); 40 }); 41 } 42 43 private struct FromImpl(string moduleName) { 44 template opDispatch(string symbolName) { 45 static if (ModuleContainsSymbol!(moduleName, symbolName)) { 46 mixin("import ", moduleName,";"); 47 mixin("alias opDispatch = ", symbolName, ";"); 48 } else { 49 static if (moduleName.length == 0) { 50 enum opDispatch = FromImpl!(symbolName)(); 51 } else { 52 enum importString = moduleName ~ "." ~ symbolName; 53 static assert( 54 CanImport!importString, 55 "Symbol \"" ~ symbolName ~ "\" not found in " ~ modueName 56 ); 57 enum opDispatch = FromImpl!importString(); 58 } 59 } 60 } 61 } 62 63 unittest { 64 static assert(!__traits(compiles, { from.std.stdio.thisFunctionDoesNotExist(42); })); 65 }