1 module ctini.ctini; 2 3 import std.algorithm; 4 import std.array; 5 import std.range; 6 import std.string; 7 8 import ctini.common; 9 10 debug import std.stdio; 11 12 public import std.typecons : Tuple; 13 14 public template IniConfig(string iniFile) { 15 enum IniConfig = mixin(parseSections(import(iniFile)).makeTuples()); 16 } 17 18 19 private: 20 21 22 /** 23 * Return the Tuple!()() declaration as a string that, 24 * when mixed-in, will return a Tuple of this section 25 */ 26 string getDeclaration(const Section section) { 27 auto sb = appender!string(); 28 29 sb ~= section.getTypeName(); 30 31 sb ~= "("; 32 //Add functin args, list of values 33 sb ~= chain( 34 section.settings.map!( 35 s => s.value 36 ), 37 section.subsections.map!( 38 ss => ss.getDeclaration() 39 ) 40 ).join(", "); 41 sb ~= ")"; 42 43 return sb.data(); 44 } 45 46 /** 47 * Returns the D type name of the section, 48 * This is an instantiation of Tuple!() 49 */ 50 string getTypeName(const Section section) { 51 auto sb = appender!string(); 52 sb ~= ("Tuple!("); 53 54 //Add template args, type followed by name 55 sb ~= chain( 56 section.settings.map!( 57 s => format("%s, \"%s\"", s.type, s.name ) 58 ), 59 section.subsections.map!( 60 ss => format("%s, \"%s\"", ss.getTypeName(), ss.name) 61 ) 62 ).join(", "); 63 sb ~= ")"; 64 65 return sb.data(); 66 } 67 68 69 string makeTuples(const Section[string] sections) { 70 //Create the Tuple!()() declaraction 71 auto sb = appender!string(); 72 73 /+ 74 debug { 75 foreach( section; sections.values ) { 76 writeln(section); 77 } 78 }+/ 79 80 sb ~= "Tuple!("; 81 //Template args -- type, "name" pairs 82 sb ~= sections.values 83 .filter!( sec => sec.parent is null ) 84 .map!( sec => format("%s, \"%s\"", sec.getTypeName(), sec.name) ) 85 .join(", "); 86 87 sb ~= ")("; 88 //Constructor args -- values (Tuple!()() declarations themselves) 89 sb ~= sections.values 90 .filter!( sec => sec.parent is null ) 91 .map!( sec => sec.getDeclaration() ) 92 .join(", "); 93 sb ~= ")"; 94 95 return sb.data(); 96 97 }