1 2 module markov.json.encoder; 3 4 import markov.chain; 5 import markov.counter; 6 import markov.serialize; 7 import markov.state; 8 9 import std.algorithm; 10 import std.array; 11 import std.conv; 12 import std.json; 13 import std.stdio; 14 import std.string; 15 16 struct JsonEncoder(T) 17 { 18 private: 19 bool _pretty; 20 21 public: 22 this(bool pretty) 23 { 24 _pretty = pretty; 25 } 26 27 string encode(ref MarkovChain!T chain) 28 { 29 JSONValue states = chain.states.map!(s => encodeState(s)).array; 30 31 return toJSON(states, _pretty); 32 } 33 34 private: 35 JSONValue encodeState(State!T state) 36 { 37 JSONValue object = ["size": state.size.text]; 38 object["counters"] = "{ }".parseJSON; 39 40 foreach(first; state.keys) 41 { 42 object["counters"][encodeKeys(first)] = encodeCounter(state.get(first)); 43 } 44 45 return object; 46 } 47 48 JSONValue encodeCounter(Counter!T counter) 49 { 50 string[string] data; 51 52 foreach(follow; counter.keys) 53 { 54 data[encodeKey(follow)] = counter.get(follow).text; 55 } 56 57 JSONValue object = data; 58 return object; 59 } 60 61 string encodeKeys(T[] keys) 62 { 63 return "[%(%s,%)]".format(keys.map!(k => encodeKey(k))); 64 } 65 66 string encodeKey(T key) 67 { 68 static if(hasEncodeProperty!(T, string)) 69 { 70 return key.encode; 71 } 72 else 73 { 74 return key.text; 75 } 76 } 77 } 78 79 string encodeJSON(T)(ref MarkovChain!T chain, bool pretty = false) 80 { 81 JsonEncoder!T encoder = JsonEncoder!T(pretty); 82 return encoder.encode(chain); 83 } 84 85 void encodeJSON(T)(ref MarkovChain!T chain, File output, bool pretty = false) 86 { 87 output.write(chain.encodeJSON(pretty)); 88 }