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 }