v.gen.c: use unmangled variant name for encoding sumtype values in json (#11554)

pull/11558/head
Anton Zavodchikov 2021-09-20 23:19:16 +05:00 committed by GitHub
parent 077c55d0c8
commit d51f8ed878
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 15 deletions

View File

@ -37,7 +37,7 @@ fn test_decode_top_level_array() {
assert x[1].age == 31 assert x[1].age == 31
} }
struct Usr { struct Human {
name string name string
} }
@ -50,7 +50,7 @@ enum Animal {
cat cat
} }
type Entity = Animal | Item | Usr | string | time.Time type Entity = Animal | Human | Item | string | time.Time
struct SomeGame { struct SomeGame {
title string title string
@ -61,7 +61,7 @@ struct SomeGame {
fn test_encode_decode_sumtype() ? { fn test_encode_decode_sumtype() ? {
game := SomeGame{ game := SomeGame{
title: 'Super Mega Game' title: 'Super Mega Game'
player: Usr{'PoopLord69'} player: Human{'Monke'}
other: [ other: [
Entity(Item{'Pen'}), Entity(Item{'Pen'}),
Item{'Cookie'}, Item{'Cookie'},
@ -70,10 +70,15 @@ fn test_encode_decode_sumtype() ? {
time.now(), time.now(),
] ]
} }
eprintln('Game: $game')
enc := json.encode(game) enc := json.encode(game)
eprintln('Encoded Game: $enc')
dec := json.decode(SomeGame, enc) ? dec := json.decode(SomeGame, enc) ?
eprintln('Decoded Game: $dec')
assert game.title == dec.title assert game.title == dec.title
assert game.player == dec.player assert game.player == dec.player
assert (game.other[4] as time.Time).unix_time() == (dec.other[4] as time.Time).unix_time() assert (game.other[4] as time.Time).unix_time() == (dec.other[4] as time.Time).unix_time()

View File

@ -92,7 +92,7 @@ $enc_fn_dec {
g.gen_struct_enc_dec(psym.info, styp, mut enc, mut dec) g.gen_struct_enc_dec(psym.info, styp, mut enc, mut dec)
} else if sym.kind == .sum_type { } else if sym.kind == .sum_type {
enc.writeln('\to = cJSON_CreateObject();') enc.writeln('\to = cJSON_CreateObject();')
// Structs. Range through fields // Sumtypes. Range through variants of sumtype
if sym.info !is ast.SumType { if sym.info !is ast.SumType {
verror('json: $sym.name is not a 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 { for variant in info.variants {
variant_typ := g.typ(variant) variant_typ := g.typ(variant)
variant_sym := g.table.get_type_symbol(variant) variant_sym := g.table.get_type_symbol(variant)
unmangled_variant_name := variant_sym.name.split('.').last()
g.gen_json_for_type(variant) g.gen_json_for_type(variant)
g.write_sumtype_casting_fn(variant, typ) 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 // ENCODING
enc.writeln('\tif (val._typ == $variant) {') enc.writeln('\tif (val._typ == $variant) {')
if variant_sym.kind == .enum_ { 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' { } 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 { } 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}') enc.writeln('\t}')
// DECODING // 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() tmp := g.new_tmp_var()
if is_js_prim(variant_typ) { if is_js_prim(variant_typ) {
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 = (${js_dec_name(variant_sym.name)})(jsonroot_$tmp);') dec.writeln('\t\t$variant_typ value = (${js_dec_name(variant_typ)})(jsonroot_$tmp);')
} else if variant_sym.kind == .enum_ { } 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);') dec.writeln('\t\t$variant_typ value = json__decode_u64(jsonroot_$tmp);')
} else if variant_sym.name == 'time.Time' { } 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));') dec.writeln('\t\t$variant_typ value = time__unix(json__decode_i64(jsonroot_$tmp));')
} else { } else {
gen_js_get_opt(js_dec_name(variant_sym.cname), variant_typ, sym.cname, tmp, gen_js_get_opt(js_dec_name(variant_typ), variant_typ, sym.cname, tmp, unmangled_variant_name, mut
variant_sym.name, mut dec, false) dec, false)
// dec.writeln('\t\tOption_${variant_typ} $tmp = json__decode_${variant_typ}(js_get(root, "$variant_sym.name"));')
dec.writeln('\t\t$variant_typ value = *($variant_typ*)(${tmp}.data);') dec.writeln('\t\t$variant_typ value = *($variant_typ*)(${tmp}.data);')
} }
dec.writeln('\t\tres = ${variant_typ}_to_sumtype_${sym.cname}(&value);') dec.writeln('\t\tres = ${variant_typ}_to_sumtype_${sym.cname}(&value);')