1 module keyvalues.keyvalue; 2 3 import std.algorithm; 4 import std.array; 5 import std.string; 6 import std.traits; 7 8 /++ 9 In-memory representation of a KeyValues object. 10 +/ 11 struct KeyValue 12 { 13 string key; ///The key of this KeyValue. 14 bool hasSubkeys; ///Whether this KeyValue has subkeys. 15 16 union 17 { 18 string value; ///The value of this KeyValue, if hasSubkeys is false. 19 KeyValue[] subkeys; ///The subkeys of this KeyValue, if hasSubkeys is true. 20 } 21 22 /++ 23 Returns all subkeys whose key equal name. 24 +/ 25 KeyValue[] opIndex(string name) 26 in { assert(hasSubkeys); } 27 body 28 { 29 return subkeys 30 .filter!(subkey => subkey.key == name) 31 .array 32 ; 33 } 34 35 /++ 36 Returns a pretty printed string representation of this KeyValue. 37 +/ 38 string toString() 39 { 40 string valueRepr; 41 42 if(hasSubkeys) 43 valueRepr = subkeys 44 .map!(sk => sk.toString) 45 .join(",\n") 46 .replace("\n", "\n ") 47 .Identity!(str => "[\n %s\n]".format(str)) 48 ; 49 else 50 valueRepr = value 51 .formatEscapes 52 .Identity!(str => `"%s"`.format(str)) 53 ; 54 55 return "KeyValue(\n \"%s\",\n %s\n)".format( 56 key.formatEscapes, 57 valueRepr.replace("\n", "\n "), 58 ); 59 } 60 61 //TODO: method to serialize to KeyValues text 62 } 63 64 private string formatEscapes(string str) 65 { 66 return str 67 .replace("\\", `\\`) 68 .replace("\"", `\"`) 69 .replace("\n", `\n`) 70 .replace("\t", `\t`) 71 ; 72 }