From d51f8ed8785e2d19c952086bb1f378ff975e857f Mon Sep 17 00:00:00 2001 From: Anton Zavodchikov Date: Mon, 20 Sep 2021 23:19:16 +0500 Subject: [PATCH] v.gen.c: use unmangled variant name for encoding sumtype values in json (#11554) --- vlib/json/json_test.v | 11 ++++++++--- vlib/v/gen/c/json.v | 24 ++++++++++++------------ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/vlib/json/json_test.v b/vlib/json/json_test.v index 53323ba3d1..a17991f971 100644 --- a/vlib/json/json_test.v +++ b/vlib/json/json_test.v @@ -37,7 +37,7 @@ fn test_decode_top_level_array() { assert x[1].age == 31 } -struct Usr { +struct Human { name string } @@ -50,7 +50,7 @@ enum Animal { cat } -type Entity = Animal | Item | Usr | string | time.Time +type Entity = Animal | Human | Item | string | time.Time struct SomeGame { title string @@ -61,7 +61,7 @@ struct SomeGame { fn test_encode_decode_sumtype() ? { game := SomeGame{ title: 'Super Mega Game' - player: Usr{'PoopLord69'} + player: Human{'Monke'} other: [ Entity(Item{'Pen'}), Item{'Cookie'}, @@ -70,10 +70,15 @@ fn test_encode_decode_sumtype() ? { time.now(), ] } + eprintln('Game: $game') enc := json.encode(game) + eprintln('Encoded Game: $enc') + dec := json.decode(SomeGame, enc) ? + eprintln('Decoded Game: $dec') + assert game.title == dec.title assert game.player == dec.player assert (game.other[4] as time.Time).unix_time() == (dec.other[4] as time.Time).unix_time() diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index fb5e4a1d06..d39ff2716d 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -92,7 +92,7 @@ $enc_fn_dec { g.gen_struct_enc_dec(psym.info, styp, mut enc, mut dec) } else if sym.kind == .sum_type { enc.writeln('\to = cJSON_CreateObject();') - // Structs. Range through fields + // Sumtypes. Range through variants of sumtype if sym.info !is ast.SumType { verror('json: $sym.name is not a sumtype') } @@ -123,6 +123,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(sym ast.TypeSymbol, mut enc strings.Builder, for variant in info.variants { variant_typ := g.typ(variant) variant_sym := g.table.get_type_symbol(variant) + unmangled_variant_name := variant_sym.name.split('.').last() g.gen_json_for_type(variant) g.write_sumtype_casting_fn(variant, typ) @@ -131,30 +132,29 @@ fn (mut g Gen) gen_sumtype_enc_dec(sym ast.TypeSymbol, mut enc strings.Builder, // ENCODING enc.writeln('\tif (val._typ == $variant) {') if variant_sym.kind == .enum_ { - enc.writeln('\t\tcJSON_AddItemToObject(o, "$variant_sym.name", json__encode_u64(*val._$variant_typ));') + enc.writeln('\t\tcJSON_AddItemToObject(o, "$unmangled_variant_name", json__encode_u64(*val._$variant_typ));') } else if variant_sym.name == 'time.Time' { - enc.writeln('\t\tcJSON_AddItemToObject(o, "$variant_sym.name", json__encode_i64(val._$variant_typ->_v_unix));') + enc.writeln('\t\tcJSON_AddItemToObject(o, "$unmangled_variant_name", json__encode_i64(val._$variant_typ->_v_unix));') } else { - enc.writeln('\t\tcJSON_AddItemToObject(o, "$variant_sym.name", json__encode_${variant_typ}(*val._$variant_typ));') + enc.writeln('\t\tcJSON_AddItemToObject(o, "$unmangled_variant_name", json__encode_${variant_typ}(*val._$variant_typ));') } enc.writeln('\t}') // DECODING - dec.writeln('\tif (strcmp("$variant_sym.name", root->child->string) == 0) {') + dec.writeln('\tif (strcmp("$unmangled_variant_name", root->child->string) == 0) {') tmp := g.new_tmp_var() if is_js_prim(variant_typ) { - gen_js_get(variant_typ, tmp, variant_sym.name, mut dec, false) - dec.writeln('\t\t$variant_typ value = (${js_dec_name(variant_sym.name)})(jsonroot_$tmp);') + gen_js_get(variant_typ, tmp, unmangled_variant_name, mut dec, false) + dec.writeln('\t\t$variant_typ value = (${js_dec_name(variant_typ)})(jsonroot_$tmp);') } else if variant_sym.kind == .enum_ { - gen_js_get(variant_typ, tmp, variant_sym.name, mut dec, false) + gen_js_get(variant_typ, tmp, unmangled_variant_name, mut dec, false) dec.writeln('\t\t$variant_typ value = json__decode_u64(jsonroot_$tmp);') } else if variant_sym.name == 'time.Time' { - gen_js_get(variant_typ, tmp, variant_sym.name, mut dec, false) + gen_js_get(variant_typ, tmp, unmangled_variant_name, mut dec, false) dec.writeln('\t\t$variant_typ value = time__unix(json__decode_i64(jsonroot_$tmp));') } else { - gen_js_get_opt(js_dec_name(variant_sym.cname), variant_typ, sym.cname, tmp, - variant_sym.name, mut dec, false) - // dec.writeln('\t\tOption_${variant_typ} $tmp = json__decode_${variant_typ}(js_get(root, "$variant_sym.name"));') + gen_js_get_opt(js_dec_name(variant_typ), variant_typ, sym.cname, tmp, unmangled_variant_name, mut + dec, false) dec.writeln('\t\t$variant_typ value = *($variant_typ*)(${tmp}.data);') } dec.writeln('\t\tres = ${variant_typ}_to_sumtype_${sym.cname}(&value);')