expanding tree when error buttons pressed
[roobuilder] / src / JsRender / JsonGen.vala
1
2 /**
3
4 based on...
5 https://gitlab.gnome.org/GNOME/json-glib/-/blob/master/json-glib/json-generator.c
6
7 note - that could probably be fixed by just adding the sort method on members List..
8
9 */
10 namespace JsRender {
11  
12         public class JsonGen : Object 
13         {
14  
15                 Json.Generator generator;
16                 Json.Node node;
17                 public bool pretty = true;
18                 public int indent = 1;
19                 public char indent_char = ' ';
20                 public JsonGen( Json.Node node )
21                 {
22                          
23                         this.generator = new Json.Generator ();
24                         this.generator.indent = this.indent;
25                         this.generator.pretty = this.pretty;
26                         this.node = node;
27                 }
28                  
29                 
30                 public string to_data()
31                 {
32                         var buffer = new GLib.StringBuilder();
33                         dump_node(buffer,0, this.node, "", false);
34                         return buffer.str;
35                 }
36                 
37                 
38
39                 void dump_node (
40                                 GLib.StringBuilder buffer,
41                                 int                     level,
42                        Json.Node        node,
43                        string           name,
44                        bool                     has_name
45                        )
46                 {
47                 
48                         
49                           if (this.pretty) {
50
51                                   for (var i = 0; i < (level * this.indent); i++) {
52                                                 buffer.append_c(this.indent_char);
53                                   }
54                           }
55
56                           if (has_name){
57                                         // fixme...
58                                         // initiate a node as a string... then output it..
59                                         //buffer.append_c( '"'); // might not be needed..
60                                         var k = new Json.Node(Json.NodeType.VALUE);
61                                         k.init_string(name);
62                                         dump_value(buffer,k);
63                                         
64                                         //buffer.append_c( '"');
65                         
66                                   if (this.pretty) {
67                                         buffer.append( " : ");
68                                   } else {
69                                         buffer.append_c( ':');
70                                 }
71                 }
72
73                         switch (node.get_node_type()) {
74                                 case Json.NodeType.NULL:
75                                   buffer.append( "null");
76                                   break;
77
78                                 case Json.NodeType.VALUE:
79                                   size_t sl;
80                                   this.generator.set_root(node);
81                                   var str = this.generator.to_data(out sl);
82                                   buffer.append( str );
83                                   break;
84
85                                 case Json.NodeType.ARRAY:
86                                   this.dump_array ( buffer, level, node.get_array());
87                                   break;
88
89                                 case Json.NodeType.OBJECT:
90                                   this.dump_object (buffer, level, node.get_object());
91                                   break;
92                         }
93                 }
94                 
95                 void dump_value (GLib.StringBuilder buffer, Json.Node node)
96                 {
97                         size_t slen;
98                         this.generator.set_root(node);
99                         buffer.append( this.generator.to_data(out slen) );
100                 }
101                 
102                 void dump_array (
103            GLib.StringBuilder buffer,
104             int           level,
105             Json.Array     array)
106                 {
107
108
109                   var array_len = array.get_length();
110                   
111                   var pretty = this.pretty;
112  
113
114                   buffer.append_c( '[');
115
116                   if (array_len == 0) {
117                            buffer.append_c( ']');
118                            return;
119                   }
120
121                   for (var i = 0; i < array_len; i++) {
122                           var cur = array.get_element ( i);
123
124                           if (i == 0 && pretty) {
125                                 buffer.append_c('\n');
126                           }
127                           this.dump_node ( buffer, level + 1, cur, "", false);
128
129                           if ((i + 1) != array_len) {
130                                 buffer.append_c( ',');
131                          }
132                           if (pretty) {
133                                 buffer.append_c( '\n');
134                         } 
135                   }
136
137                   if (pretty) {
138                           for (var i = 0; i < (level * this.indent); i++) {
139                                 buffer.append_c(this.indent_char);
140                          }
141                   }
142
143                   buffer.append_c( ']');
144                 }
145
146                  void dump_object (
147                         GLib.StringBuilder buffer,
148                         int           level,
149                         Json.Object     object)
150                 {
151
152
153                   var  pretty = this.pretty;
154
155
156
157                   buffer.append_c('{');
158                   buffer.append_c(  '\n');
159                   var members = object.get_members();
160                   members.sort(GLib.strcmp);
161                   
162                         var mi = -1;
163                         members.foreach ( (member_name) => {
164                                 mi++;
165
166                                 var cur = object.get_member( member_name);
167
168                                 //if (mi > 0 && pretty) {
169                                 //      buffer.append_c(  '\n');
170                                 //}
171
172                                 dump_node (buffer, level + 1, cur,  member_name, true);
173
174                                 if (mi < members.length()-1) {
175                                         buffer.append_c(  ',');
176                                 }
177                                 if (pretty) {
178                                         buffer.append_c(  '\n');
179                                 }
180                         });
181
182                         if (pretty)
183                         {
184                                 for (var i = 0; i < (level * this.indent); i++) {
185                                         buffer.append_c( this.indent_char);
186                                 }
187                         }
188
189                  buffer.append_c(  '}');
190                 }
191
192
193     }                                   
194                                         
195 }
196
197
198 /*
199 compile : 
200
201 valac --pkg json-glib-1.0 -D JSON_TESTCODE Json.vala
202 */
203
204 #if JSON_TESTCODE
205 void main (string[] args) {
206
207         var testjson = """
208         {"quiz":{"sport":{"q1":{"question":"Which one is correct team name in NBA?","options":["New York Bulls",
209         "Los Angeles Kings","Golden State Warriros","Huston Rocket"],"answer":"Huston Rocket"}},"maths":
210         {"q1":{"question":"5 + 7 = ?","options":["10","11","12","13"],"answer":"12"},"q2":
211         {"question":"12 - 8 = ?","options":["1","2","3","4"],"answer":"4"}}}}
212         """;
213         var parser =   new Json.Parser ();
214         parser.load_from_data(testjson);
215         
216         var node = parser.get_root ();
217
218         var js = new JsRender.JsonGen(node);
219         print("OUT: %s", js.to_data());
220         
221         
222         
223 }
224
225
226
227
228
229
230
231