@@ -86,10 +86,13 @@ $enc_fn_dec {
86
86
return
87
87
}
88
88
enc.writeln ('\t o = cJSON_CreateObject();' )
89
- if psym.info ! is ast.Struct {
89
+ if psym.info is ast.Struct {
90
+ g.gen_struct_enc_dec (psym.info, styp, mut enc, mut dec)
91
+ } else if psym.kind == .sum_type {
92
+ verror ('json: $sym.name aliased sumtypes does not work at the moment' )
93
+ } else {
90
94
verror ('json: $sym.name is not struct' )
91
95
}
92
- g.gen_struct_enc_dec (psym.info, styp, mut enc, mut dec)
93
96
} else if sym.kind == .sum_type {
94
97
enc.writeln ('\t o = cJSON_CreateObject();' )
95
98
// Sumtypes. Range through variants of sumtype
@@ -118,46 +121,164 @@ $enc_fn_dec {
118
121
[inline ]
119
122
fn (mut g Gen) gen_sumtype_enc_dec (sym ast.TypeSymbol, mut enc strings.Builder, mut dec strings.Builder) {
120
123
info := sym.info as ast.SumType
124
+ type_var := g.new_tmp_var ()
121
125
typ := sym.idx
122
126
127
+ // DECODING (inline)
128
+ $if ! json_no_inline_sumtypes ? {
129
+ type_tmp := g.new_tmp_var ()
130
+ dec.writeln ('\t if (cJSON_IsObject(root)) {' )
131
+ dec.writeln ('\t\t cJSON* $type_tmp = js_get(root, "_type");' )
132
+ dec.writeln ('\t\t if ($type_tmp != 0) {' )
133
+ dec.writeln ('\t\t\t char* $type_var = cJSON_GetStringValue($type_tmp );' )
134
+ // dec.writeln('\t\t\tcJSON_DeleteItemFromObjectCaseSensitive(root, "_type");')
135
+ }
136
+
137
+ mut variant_types := []string {}
138
+ mut variant_symbols := []ast.TypeSymbol{}
139
+ mut at_least_one_prim := false
123
140
for variant in info.variants {
124
141
variant_typ := g.typ (variant)
142
+ variant_types << variant_typ
125
143
variant_sym := g.table.get_type_symbol (variant)
144
+ variant_symbols << variant_sym
145
+ at_least_one_prim = at_least_one_prim || is_js_prim (variant_typ)
146
+ || variant_sym.kind == .enum_ || variant_sym.name == 'time.Time'
126
147
unmangled_variant_name := variant_sym.name.split ('.' ).last ()
127
148
149
+ // TODO: Do not generate dec/enc for 'time.Time', because we handle it by saving it as u64
128
150
g.gen_json_for_type (variant)
151
+
152
+ // Helpers for decoding
129
153
g.write_sumtype_casting_fn (variant, typ)
130
154
g.definitions.writeln ('static inline $sym.cname ${variant_typ} _to_sumtype_${sym.cname} ($variant_typ * x);' )
131
155
132
156
// ENCODING
133
157
enc.writeln ('\t if (val._typ == $variant ) {' )
134
- if variant_sym.kind == .enum_ {
135
- enc.writeln ('\t\t cJSON_AddItemToObject(o, "$unmangled_variant_name ", json__encode_u64(*val._$variant_typ ));' )
136
- } else if variant_sym.name == 'time.Time' {
137
- enc.writeln ('\t\t cJSON_AddItemToObject(o, "$unmangled_variant_name ", json__encode_i64(val._$variant_typ ->_v_unix));' )
138
- } else {
139
- enc.writeln ('\t\t cJSON_AddItemToObject(o, "$unmangled_variant_name ", json__encode_${variant_typ} (*val._$variant_typ ));' )
158
+ $if json_no_inline_sumtypes ? {
159
+ if variant_sym.kind == .enum_ {
160
+ enc.writeln ('\t\t cJSON_AddItemToObject(o, "$unmangled_variant_name ", ${js_enc_name('u64')} (*val._$variant_typ ));' )
161
+ } else if variant_sym.name == 'time.Time' {
162
+ enc.writeln ('\t\t cJSON_AddItemToObject(o, "$unmangled_variant_name ", ${js_enc_name('i64')} (val._$variant_typ ->_v_unix));' )
163
+ } else {
164
+ enc.writeln ('\t\t cJSON_AddItemToObject(o, "$unmangled_variant_name ", ${js_enc_name(variant_typ)} (*val._$variant_typ ));' )
165
+ }
166
+ } $else {
167
+ if is_js_prim (variant_typ) {
168
+ enc.writeln ('\t\t o = ${js_enc_name(variant_typ)} (*val._$variant_typ );' )
169
+ } else if variant_sym.kind == .enum_ {
170
+ enc.writeln ('\t\t o = ${js_enc_name('u64')} (*val._$variant_typ );' )
171
+ } else if variant_sym.name == 'time.Time' {
172
+ enc.writeln ('\t\t cJSON_AddItemToObject(o, "_type", cJSON_CreateString("$unmangled_variant_name "));' )
173
+ enc.writeln ('\t\t cJSON_AddItemToObject(o, "value", ${js_enc_name('i64')} (val._$variant_typ ->_v_unix));' )
174
+ } else {
175
+ enc.writeln ('\t\t o = ${js_enc_name(variant_typ)} (*val._$variant_typ );' )
176
+ enc.writeln ('\t\t cJSON_AddItemToObject(o, "_type", cJSON_CreateString("$unmangled_variant_name "));' )
177
+ }
140
178
}
141
179
enc.writeln ('\t }' )
142
180
143
181
// DECODING
144
- dec.writeln ('\t if (strcmp("$unmangled_variant_name ", root->child->string) == 0) {' )
145
182
tmp := g.new_tmp_var ()
146
- if is_js_prim (variant_typ) {
147
- gen_js_get (variant_typ, tmp, unmangled_variant_name, mut dec, false )
148
- dec.writeln ('\t\t $variant_typ value = (${js_dec_name(variant_typ)} )(jsonroot_$tmp );' )
149
- } else if variant_sym.kind == .enum_ {
150
- gen_js_get (variant_typ, tmp, unmangled_variant_name, mut dec, false )
151
- dec.writeln ('\t\t $variant_typ value = json__decode_u64(jsonroot_$tmp );' )
152
- } else if variant_sym.name == 'time.Time' {
153
- gen_js_get (variant_typ, tmp, unmangled_variant_name, mut dec, false )
154
- dec.writeln ('\t\t $variant_typ value = time__unix(json__decode_i64(jsonroot_$tmp ));' )
155
- } else {
156
- gen_js_get_opt (js_dec_name (variant_typ), variant_typ, sym.cname, tmp, unmangled_variant_name, mut
157
- dec, false )
158
- dec.writeln ('\t\t $variant_typ value = *($variant_typ *)(${tmp} .data);' )
183
+ $if json_no_inline_sumtypes ? {
184
+ dec.writeln ('\t if (strcmp("$unmangled_variant_name ", root->child->string) == 0) {' )
185
+ if is_js_prim (variant_typ) {
186
+ gen_js_get (variant_typ, tmp, unmangled_variant_name, mut dec, true )
187
+ dec.writeln ('\t\t $variant_typ value = ${js_dec_name(variant_typ)} (jsonroot_$tmp );' )
188
+ } else if variant_sym.kind == .enum_ {
189
+ gen_js_get (variant_typ, tmp, unmangled_variant_name, mut dec, true )
190
+ dec.writeln ('\t\t $variant_typ value = ${js_dec_name('u64')} (jsonroot_$tmp );' )
191
+ } else if variant_sym.name == 'time.Time' {
192
+ gen_js_get (variant_typ, tmp, unmangled_variant_name, mut dec, true )
193
+ dec.writeln ('\t\t $variant_typ value = time__unix(${js_dec_name('i64')} (jsonroot_$tmp ));' )
194
+ } else {
195
+ gen_js_get_opt (js_dec_name (variant_typ), variant_typ, sym.cname, tmp,
196
+ unmangled_variant_name, mut dec, true )
197
+ dec.writeln ('\t\t $variant_typ value = *($variant_typ *)(${tmp} .data);' )
198
+ }
199
+ dec.writeln ('\t\t res = ${variant_typ} _to_sumtype_${sym.cname} (&value);' )
200
+ dec.writeln ('\t }' )
201
+ } $else {
202
+ if variant_sym.name == 'time.Time' {
203
+ dec.writeln ('\t\t\t if (strcmp("Time", $type_var ) == 0) {' )
204
+ gen_js_get (sym.cname, tmp, 'value' , mut dec, true )
205
+ dec.writeln ('\t\t\t\t $variant_typ $tmp = time__unix(${js_dec_name('i64')} (jsonroot_$tmp ));' )
206
+ dec.writeln ('\t\t\t\t res = ${variant_typ} _to_sumtype_${sym.cname} (&$tmp );' )
207
+ dec.writeln ('\t\t\t }' )
208
+ } else if ! is_js_prim (variant_typ) && variant_sym.kind != .enum_ {
209
+ dec.writeln ('\t\t\t if (strcmp("$unmangled_variant_name ", $type_var ) == 0) {' )
210
+ dec.writeln ('\t\t\t\t Option_$variant_typ $tmp = ${js_dec_name(variant_typ)} (root);' )
211
+ dec.writeln ('\t\t\t\t if (${tmp} .state != 0) {' )
212
+ dec.writeln ('\t\t\t\t\t return (Option_$sym.cname ){ .state = ${tmp} .state, .err = ${tmp} .err, .data = {0} };' )
213
+ dec.writeln ('\t\t\t\t }' )
214
+ dec.writeln ('\t\t\t\t res = ${variant_typ} _to_sumtype_${sym.cname} (($variant_typ *)${tmp} .data);' )
215
+ dec.writeln ('\t\t\t }' )
216
+ }
217
+ }
218
+ }
219
+
220
+ // DECODING (inline)
221
+ $if ! json_no_inline_sumtypes ? {
222
+ dec.writeln ('\t\t }' )
223
+
224
+ mut number_is_met := false
225
+ mut string_is_met := false
226
+ mut last_number_type := ''
227
+
228
+ if at_least_one_prim {
229
+ dec.writeln ('\t } else {' )
230
+
231
+ if 'bool' in variant_types {
232
+ var_t := 'bool'
233
+ dec.writeln ('\t\t if (cJSON_IsBool(root)) {' )
234
+ dec.writeln ('\t\t\t $var_t value = ${js_dec_name(var_t)} (root);' )
235
+ dec.writeln ('\t\t\t res = ${var_t} _to_sumtype_${sym.cname} (&value);' )
236
+ dec.writeln ('\t\t }' )
237
+ }
238
+
239
+ for i, var_t in variant_types {
240
+ if variant_symbols[i].kind == .enum_ {
241
+ if number_is_met {
242
+ var_num := var_t.replace ('__' , '.' )
243
+ last_num := last_number_type.replace ('__' , '.' )
244
+ verror ('json: can not decode `$sym.name ` sumtype, too many numeric types (conflict of `$last_num ` and `$var_num `), you can try to use alias for `$var_num ` or compile v with `json_no_inline_sumtypes` flag' )
245
+ }
246
+ number_is_met = true
247
+ last_number_type = var_t
248
+ dec.writeln ('\t\t if (cJSON_IsNumber(root)) {' )
249
+ dec.writeln ('\t\t\t $var_t value = ${js_dec_name('u64')} (root);' )
250
+ dec.writeln ('\t\t\t res = ${var_t} _to_sumtype_${sym.cname} (&value);' )
251
+ dec.writeln ('\t\t }' )
252
+ }
253
+
254
+ if var_t in ['string' , 'rune' ] {
255
+ if string_is_met {
256
+ var_num := var_t.replace ('__' , '.' )
257
+ verror ('json: can not decode `$sym.name ` sumtype, too many string types (conflict of `string` and `rune`), you can try to use alias for `$var_num ` or compile v with `json_no_inline_sumtypes` flag' )
258
+ }
259
+ string_is_met = true
260
+ dec.writeln ('\t\t if (cJSON_IsString(root)) {' )
261
+ dec.writeln ('\t\t\t $var_t value = ${js_dec_name(var_t)} (root);' )
262
+ dec.writeln ('\t\t\t res = ${var_t} _to_sumtype_${sym.cname} (&value);' )
263
+ dec.writeln ('\t\t }' )
264
+ }
265
+
266
+ if var_t in ['i64' , 'int' , 'i8' , 'u64' , 'u32' , 'u16' , 'byte' , 'u8' , 'rune' , 'f64' ,
267
+ 'f32' ] {
268
+ if number_is_met {
269
+ var_num := var_t.replace ('__' , '.' )
270
+ last_num := last_number_type.replace ('__' , '.' )
271
+ verror ('json: can not decode `$sym.name ` sumtype, too many numeric types (conflict of `$last_num ` and `$var_num `), you can try to use alias for `$var_num ` or compile v with `json_no_inline_sumtypes` flag' )
272
+ }
273
+ number_is_met = true
274
+ last_number_type = var_t
275
+ dec.writeln ('\t\t if (cJSON_IsNumber(root)) {' )
276
+ dec.writeln ('\t\t\t $var_t value = ${js_dec_name(var_t)} (root);' )
277
+ dec.writeln ('\t\t\t res = ${var_t} _to_sumtype_${sym.cname} (&value);' )
278
+ dec.writeln ('\t\t }' )
279
+ }
280
+ }
159
281
}
160
- dec.writeln ('\t\t res = ${variant_typ} _to_sumtype_${sym.cname} (&value);' )
161
282
dec.writeln ('\t }' )
162
283
}
163
284
}
@@ -294,8 +415,8 @@ fn js_dec_name(typ string) string {
294
415
}
295
416
296
417
fn is_js_prim (typ string ) bool {
297
- return typ in ['int' , 'string' , 'bool' , 'f32' , 'f64' , 'i8' , 'i16' , 'i64' , 'u16 ' , 'u32' , 'u64 ' ,
298
- 'byte' ]
418
+ return typ in ['int' , 'rune' , ' string' , 'bool' , 'f32' , 'f64' , 'i8' , 'i16' , 'i64' , 'u8 ' , 'u16 ' ,
419
+ 'u32' , 'u64' , ' byte' ]
299
420
}
300
421
301
422
fn (mut g Gen) decode_array (value_type ast.Type) string {
0 commit comments