1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: fix json encode struct with optional field (#16866)

This commit is contained in:
yuyi 2023-01-04 18:41:07 +08:00 committed by GitHub
parent 0a6fc6d280
commit b8571c964d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 3 deletions

View File

@ -0,0 +1,20 @@
import json
struct Foo {
name string
num ?int
}
fn test_json_encode_struct_with_optional_field() {
f1 := Foo{
name: 'hello'
}
ret1 := json.encode(f1)
println(ret1)
assert ret1 == '{"name":"hello","num":null}'
f2 := Foo{'hello', 22}
ret2 := json.encode(f2)
println(ret2)
assert ret2 == '{"name":"hello","num":22}'
}

View File

@ -1061,7 +1061,11 @@ fn (mut g Gen) optional_type_name(t ast.Type) (string, string) {
}
fn (mut g Gen) result_type_name(t ast.Type) (string, string) {
base := g.base_type(t)
mut base := g.base_type(t)
if t.has_flag(.optional) {
g.register_optional(t)
base = '_option_' + base
}
mut styp := ''
sym := g.table.sym(t)
if sym.language == .c && sym.kind == .struct_ {

View File

@ -26,7 +26,7 @@ import strings
fn (mut g Gen) gen_json_for_type(typ ast.Type) {
utyp := g.unwrap_generic(typ).set_nr_muls(0)
sym := g.table.sym(utyp)
if is_js_prim(sym.name) || sym.kind == .enum_ {
if (is_js_prim(sym.name) && !utyp.has_flag(.optional)) || sym.kind == .enum_ {
return
}
g.json_types << utyp
@ -54,10 +54,14 @@ fn (mut g Gen) gen_jsons() {
mut init_styp := '${styp} res'
if sym.kind == .struct_ {
init_styp += ' = '
init_styp += g.expr_string(ast.Expr(ast.StructInit{
g.set_current_pos_as_last_stmt_pos()
pos := g.out.len
g.write(init_styp)
g.expr(ast.Expr(ast.StructInit{
typ: utyp
typ_str: styp
}))
init_styp = g.out.cut_to(pos).trim_space()
}
dec.writeln('
@ -144,6 +148,8 @@ ${enc_fn_dec} {
verror('json: ${sym.name} is not a sumtype')
}
g.gen_sumtype_enc_dec(sym, mut enc, mut dec)
} else if utyp.has_flag(.optional) {
g.gen_option_enc_dec(utyp, mut enc, mut dec)
} else {
enc.writeln('\to = cJSON_CreateObject();')
// Structs. Range through fields
@ -162,6 +168,15 @@ ${enc_fn_dec} {
}
}
fn (mut g Gen) gen_option_enc_dec(typ ast.Type, mut enc strings.Builder, mut dec strings.Builder) {
enc.writeln('\tif (val.state == 2) {')
enc.writeln('\t\treturn cJSON_CreateNull();')
enc.writeln('\t}')
type_str := g.typ(typ.clear_flag(.optional))
encode_name := js_enc_name(type_str)
enc.writeln('\to = ${encode_name}(*(${type_str}*)val.data);')
}
[inline]
fn (mut g Gen) gen_sumtype_enc_dec(sym ast.TypeSymbol, mut enc strings.Builder, mut dec strings.Builder) {
info := sym.info as ast.SumType