Substring to strip off the end of struct names when reading them from the input range. Defaults to "Settings". May be empty.
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 { 64 65 FooSettings foo; 66 serialisedFileContents 67 .splitter("\n") 68 .deserialise(missing, invalid, foo); 69 70 with (foo) 71 { 72 import std.math : isClose; 73 74 assert((i == 42), i.text); 75 assert((ia == [ 1, 2, -3, 4, 5 ]), ia.text); 76 assert((s == "hello world!"), s); 77 assert((sa == [ "hello", "world", "!" ]), sa.text); 78 assert(b); 79 assert((ba == [ true, false, true ]), ba.text); 80 assert((f == 3.14f), f.text); 81 assert((fa == [ 0.0f, 1.1f, -2.2f, 3.3f ]), fa.text); 82 assert((d == 99.9), d.text); 83 84 // rounding errors with LDC on Windows 85 assert(da[0].isClose(99.9999), da[0].text); 86 assert(da[1].isClose(0.0001), da[1].text); 87 assert(da[2].isClose(-1.0), da[2].text); 88 89 with (FooSettings.Bar) 90 { 91 assert((bar == oorgle), bar.text); 92 assert((bara == [ blaawp, oorgle, blaawp ]), bara.text); 93 } 94 } 95 96 import std.algorithm.searching : canFind; 97 98 assert("Foo" in missing); 99 assert(missing["Foo"].canFind("missing")); 100 assert(!missing["Foo"].canFind("commented")); 101 assert(!missing["Foo"].canFind("slashed")); 102 assert("Foo" in invalid); 103 assert(invalid["Foo"].canFind("invalid")); 104 } 105 { 106 struct DifferentSection 107 { 108 string ignored; 109 string because; 110 int nil; 111 string naN; 112 } 113 114 // Can read other structs from the same file 115 116 DifferentSection diff; 117 serialisedFileContents 118 .splitter("\n") 119 .deserialise(missing, invalid, diff); 120 121 with (diff) 122 { 123 assert((ignored == "completely"), ignored); 124 assert((because == "no DifferentSection struct was passed"), because); 125 assert((nil == 5), nil.text); 126 assert((naN == `!"¤%&/`), naN); 127 } 128 } 129 { 130 enum Letters { abc, def, ghi } 131 132 struct StructWithSuffixToStrip 133 { 134 Letters lt = Letters.def; 135 } 136 137 enum configContents = 138 `[Struct] 139 lt ghi 140 `; 141 StructWithSuffixToStrip st; 142 configContents 143 .splitter("\n") 144 .deserialise!("WithSuffixToStrip")(missing, invalid, st); 145 146 assert(st.lt == Letters.ghi); 147 } 148 { 149 class Class 150 { 151 enum Bar { blaawp = 5, oorgle = -1 } 152 int i; 153 string s; 154 bool b; 155 float f; 156 double d; 157 Bar bar; 158 string omitted; 159 160 @Separator(",") 161 { 162 int[] ia; 163 string[] sa; 164 bool[] ba; 165 float[] fa; 166 double[] da; 167 Bar[] bara; 168 } 169 } 170 171 enum serialisedFileContentsClass = 172 `[Class] 173 i 42 174 ia 1,2,-3,4,5 175 s hello world! 176 sa hello,world,! 177 b true 178 ba true,false,true 179 wrong name 180 181 # comment 182 ; other type of comment 183 // third type of comment 184 185 f 3.14 #hirp 186 fa 0.0,1.1,-2.2,3.3 ;herp 187 d 99.9 //derp 188 da 99.9999,0.0001,-1 189 bar oorgle 190 bara blaawp,oorgle,blaawp`; 191 192 Class c = new Class; 193 serialisedFileContentsClass 194 .splitter("\n") 195 .deserialise(missing, invalid, c); 196 197 with (c) 198 { 199 import std.math : isClose; 200 201 assert((i == 42), i.text); 202 assert((ia == [ 1, 2, -3, 4, 5 ]), ia.text); 203 assert((s == "hello world!"), s); 204 assert((sa == [ "hello", "world", "!" ]), sa.text); 205 assert(b); 206 assert((ba == [ true, false, true ]), ba.text); 207 assert((f == 3.14f), f.text); 208 assert((fa == [ 0.0f, 1.1f, -2.2f, 3.3f ]), fa.text); 209 assert((d == 99.9), d.text); 210 211 // rounding errors with LDC on Windows 212 assert(da[0].isClose(99.9999), da[0].text); 213 assert(da[1].isClose(0.0001), da[1].text); 214 assert(da[2].isClose(-1.0), da[2].text); 215 216 with (Class.Bar) 217 { 218 assert((bar == oorgle), b.text); 219 assert((bara == [ blaawp, oorgle, blaawp ]), bara.text); 220 } 221 } 222 }
Takes an input range containing serialised entry-value text and applies the contents therein to one or more passed struct/class objects.