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 }