Input range from which to read the serialised text.
Out reference of an associative array of string arrays of expected entries that were missing.
Out reference of an associative array of string arrays of unexpected entries that did not belong.
Reference variadic list of one or more objects to apply the deserialised values to.
DeserialisationException if there were bad lines.
struct Foo { // ... } struct Bar { // ... } Foo foo; Bar bar; string[][string] missingEntries; string[][string] invalidEntries; string fromFile = readText("configuration.conf"); fromFile .splitter("\n") .deserialise(missingEntries, invalidEntries, foo, bar);
1 import lu.uda : Separator; 2 import std.algorithm.iteration : splitter; 3 import std.conv : text; 4 5 struct FooSettings 6 { 7 enum Bar { blaawp = 5, oorgle = -1 } 8 int i; 9 string s; 10 bool b; 11 float f; 12 double d; 13 Bar bar; 14 string commented; 15 string slashed; 16 int missing; 17 //bool invalid; 18 19 @Separator(",") 20 { 21 int[] ia; 22 string[] sa; 23 bool[] ba; 24 float[] fa; 25 double[] da; 26 Bar[] bara; 27 } 28 } 29 30 enum serialisedFileContents = 31 `[Foo] 32 i 42 33 ia 1,2,-3,4,5 34 s hello world! 35 sa hello,world,! 36 b true 37 ba true,false,true 38 invalid name 39 40 # comment 41 ; other type of comment 42 // third type of comment 43 44 f 3.14 #hirp 45 fa 0.0,1.1,-2.2,3.3 ;herp 46 d 99.9 //derp 47 da 99.9999,0.0001,-1 48 bar oorgle 49 bara blaawp,oorgle,blaawp 50 #commented hi 51 // slashed also commented 52 invalid ho 53 54 [DifferentSection] 55 ignored completely 56 because no DifferentSection struct was passed 57 nil 5 58 naN !"¤%&/`; 59 60 string[][string] missing; 61 string[][string] invalid; 62 63 FooSettings foo; 64 serialisedFileContents 65 .splitter("\n") 66 .deserialise(missing, invalid, foo); 67 68 with (foo) 69 { 70 assert((i == 42), i.text); 71 assert((ia == [ 1, 2, -3, 4, 5 ]), ia.text); 72 assert((s == "hello world!"), s); 73 assert((sa == [ "hello", "world", "!" ]), sa.text); 74 assert(b); 75 assert((ba == [ true, false, true ]), ba.text); 76 assert((f == 3.14f), f.text); 77 assert((fa == [ 0.0f, 1.1f, -2.2f, 3.3f ]), fa.text); 78 assert((d == 99.9), d.text); 79 80 static if (__VERSION__ >= 2091) 81 { 82 import std.math : isClose; 83 } 84 else 85 { 86 import std.math : approxEqual; 87 alias isClose = approxEqual; 88 } 89 90 // rounding errors with LDC on Windows 91 assert(isClose(da[0], 99.9999), da[0].text); 92 assert(isClose(da[1], 0.0001), da[1].text); 93 assert(isClose(da[2], -1.0), da[2].text); 94 95 with (FooSettings.Bar) 96 { 97 assert((bar == oorgle), bar.text); 98 assert((bara == [ blaawp, oorgle, blaawp ]), bara.text); 99 } 100 } 101 102 import std.algorithm.searching : canFind; 103 104 assert("Foo" in missing); 105 assert(missing["Foo"].canFind("missing")); 106 assert(!missing["Foo"].canFind("commented")); 107 assert(!missing["Foo"].canFind("slashed")); 108 assert("Foo" in invalid); 109 assert(invalid["Foo"].canFind("invalid")); 110 111 struct DifferentSection 112 { 113 string ignored; 114 string because; 115 int nil; 116 string naN; 117 } 118 119 // Can read other structs from the same file 120 121 DifferentSection diff; 122 serialisedFileContents 123 .splitter("\n") 124 .deserialise(missing, invalid, diff); 125 126 with (diff) 127 { 128 assert((ignored == "completely"), ignored); 129 assert((because == "no DifferentSection struct was passed"), because); 130 assert((nil == 5), nil.text); 131 assert((naN == `!"¤%&/`), naN); 132 } 133 134 enum Letters { abc, def, ghi, } 135 136 struct Struct 137 { 138 Letters lt = Letters.def; 139 } 140 141 enum configContents = 142 `[Struct] 143 lt ghi 144 `; 145 Struct st; 146 configContents 147 .splitter("\n") 148 .deserialise(missing, invalid, st); 149 150 assert(st.lt == Letters.ghi); 151 152 class Class 153 { 154 enum Bar { blaawp = 5, oorgle = -1 } 155 int i; 156 string s; 157 bool b; 158 float f; 159 double d; 160 Bar bar; 161 string omitted; 162 163 @Separator(",") 164 { 165 int[] ia; 166 string[] sa; 167 bool[] ba; 168 float[] fa; 169 double[] da; 170 Bar[] bara; 171 } 172 } 173 174 enum serialisedFileContentsClass = 175 `[Class] 176 i 42 177 ia 1,2,-3,4,5 178 s hello world! 179 sa hello,world,! 180 b true 181 ba true,false,true 182 wrong name 183 184 # comment 185 ; other type of comment 186 // third type of comment 187 188 f 3.14 #hirp 189 fa 0.0,1.1,-2.2,3.3 ;herp 190 d 99.9 //derp 191 da 99.9999,0.0001,-1 192 bar oorgle 193 bara blaawp,oorgle,blaawp`; 194 195 Class c = new Class; 196 serialisedFileContentsClass 197 .splitter("\n") 198 .deserialise(missing, invalid, c); 199 200 with (c) 201 { 202 assert((i == 42), i.text); 203 assert((ia == [ 1, 2, -3, 4, 5 ]), ia.text); 204 assert((s == "hello world!"), s); 205 assert((sa == [ "hello", "world", "!" ]), sa.text); 206 assert(b); 207 assert((ba == [ true, false, true ]), ba.text); 208 assert((f == 3.14f), f.text); 209 assert((fa == [ 0.0f, 1.1f, -2.2f, 3.3f ]), fa.text); 210 assert((d == 99.9), d.text); 211 212 static if (__VERSION__ >= 2091) 213 { 214 import std.math : isClose; 215 } 216 else 217 { 218 import std.math : approxEqual; 219 alias isClose = approxEqual; 220 } 221 222 // rounding errors with LDC on Windows 223 assert(isClose(da[0], 99.9999), da[0].text); 224 assert(isClose(da[1], 0.0001), da[1].text); 225 assert(isClose(da[2], -1.0), da[2].text); 226 227 with (Class.Bar) 228 { 229 assert((bar == oorgle), b.text); 230 assert((bara == [ blaawp, oorgle, blaawp ]), bara.text); 231 } 232 }
Takes an input range containing serialised entry-value text and applies the contents therein to one or more passed struct/class objects.