mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
json: fix option alias support (#18801)
This commit is contained in:
parent
e7e5a07aa2
commit
7fe794a974
41
vlib/json/json_option_alias_test.v
Normal file
41
vlib/json/json_option_alias_test.v
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
optional_alias ?MyAlias // primitive
|
||||||
|
optional_struct ?MyAlias2 // complex
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Complex {
|
||||||
|
a int = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
type MyAlias = int
|
||||||
|
type MyAlias2 = Complex
|
||||||
|
|
||||||
|
fn test_empty() {
|
||||||
|
test := Test{}
|
||||||
|
encoded := json.encode(test)
|
||||||
|
assert dump(encoded) == '{}'
|
||||||
|
assert json.decode(Test, '{}')! == test
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_value() {
|
||||||
|
test := Test{
|
||||||
|
optional_alias: 1
|
||||||
|
}
|
||||||
|
encoded := json.encode(test)
|
||||||
|
assert dump(encoded) == '{"optional_alias":1}'
|
||||||
|
assert json.decode(Test, '{"optional_alias":1}')! == test
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_value_2() {
|
||||||
|
test := Test{
|
||||||
|
optional_alias: 1
|
||||||
|
optional_struct: Complex{
|
||||||
|
a: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
encoded := json.encode(test)
|
||||||
|
assert dump(encoded) == '{"optional_alias":1,"optional_struct":{"a":1}}'
|
||||||
|
assert json.decode(Test, '{"optional_alias":1,"optional_struct":{"a":1}}')! == test
|
||||||
|
}
|
@ -148,8 +148,13 @@ ${enc_fn_dec} {
|
|||||||
parent_typ := a.parent_type
|
parent_typ := a.parent_type
|
||||||
psym := g.table.sym(parent_typ)
|
psym := g.table.sym(parent_typ)
|
||||||
if is_js_prim(g.typ(parent_typ)) {
|
if is_js_prim(g.typ(parent_typ)) {
|
||||||
|
if utyp.has_flag(.option) {
|
||||||
|
g.gen_json_for_type(parent_typ.set_flag(.option))
|
||||||
|
g.gen_option_enc_dec(parent_typ.set_flag(.option), mut enc, mut dec)
|
||||||
|
} else {
|
||||||
g.gen_json_for_type(parent_typ)
|
g.gen_json_for_type(parent_typ)
|
||||||
g.gen_prim_enc_dec(parent_typ, mut enc, mut dec)
|
g.gen_prim_enc_dec(parent_typ, mut enc, mut dec)
|
||||||
|
}
|
||||||
} else if psym.info is ast.Struct {
|
} else if psym.info is ast.Struct {
|
||||||
enc.writeln('\to = cJSON_CreateObject();')
|
enc.writeln('\to = cJSON_CreateObject();')
|
||||||
g.gen_struct_enc_dec(utyp, psym.info, ret_styp, mut enc, mut dec)
|
g.gen_struct_enc_dec(utyp, psym.info, ret_styp, mut enc, mut dec)
|
||||||
@ -163,6 +168,8 @@ ${enc_fn_dec} {
|
|||||||
g.gen_json_for_type(m.value_type)
|
g.gen_json_for_type(m.value_type)
|
||||||
dec.writeln(g.decode_map(utyp, m.key_type, m.value_type, ret_styp))
|
dec.writeln(g.decode_map(utyp, m.key_type, m.value_type, ret_styp))
|
||||||
enc.writeln(g.encode_map(utyp, m.key_type, m.value_type))
|
enc.writeln(g.encode_map(utyp, m.key_type, m.value_type))
|
||||||
|
} else if utyp.has_flag(.option) {
|
||||||
|
g.gen_option_enc_dec(utyp, mut enc, mut dec)
|
||||||
} else {
|
} else {
|
||||||
verror('json: ${sym.name} is not struct')
|
verror('json: ${sym.name} is not struct')
|
||||||
}
|
}
|
||||||
@ -684,9 +691,14 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
dec.writeln('\t}')
|
dec.writeln('\t}')
|
||||||
} else if field_sym.kind == .alias {
|
} else if field_sym.kind == .alias {
|
||||||
alias := field_sym.info as ast.Alias
|
alias := field_sym.info as ast.Alias
|
||||||
parent_type := g.typ(alias.parent_type)
|
parent_type := if field.typ.has_flag(.option) {
|
||||||
parent_dec_name := js_dec_name(parent_type)
|
alias.parent_type.set_flag(.option)
|
||||||
if is_js_prim(parent_type) {
|
} else {
|
||||||
|
alias.parent_type
|
||||||
|
}
|
||||||
|
sparent_type := g.typ(parent_type)
|
||||||
|
parent_dec_name := js_dec_name(sparent_type)
|
||||||
|
if is_js_prim(sparent_type) {
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
gen_js_get(styp, tmp, name, mut dec, is_required)
|
gen_js_get(styp, tmp, name, mut dec, is_required)
|
||||||
dec.writeln('\tif (jsonroot_${tmp}) {')
|
dec.writeln('\tif (jsonroot_${tmp}) {')
|
||||||
@ -697,7 +709,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
}
|
}
|
||||||
dec.writeln('\t}')
|
dec.writeln('\t}')
|
||||||
} else {
|
} else {
|
||||||
g.gen_json_for_type(alias.parent_type)
|
g.gen_json_for_type(parent_type)
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
gen_js_get_opt(dec_name, field_type, styp, tmp, name, mut dec, is_required)
|
gen_js_get_opt(dec_name, field_type, styp, tmp, name, mut dec, is_required)
|
||||||
dec.writeln('\tif (jsonroot_${tmp}) {')
|
dec.writeln('\tif (jsonroot_${tmp}) {')
|
||||||
@ -772,9 +784,13 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
if !is_js_prim(field_type) {
|
if !is_js_prim(field_type) {
|
||||||
if field_sym.kind == .alias {
|
if field_sym.kind == .alias {
|
||||||
ainfo := field_sym.info as ast.Alias
|
ainfo := field_sym.info as ast.Alias
|
||||||
|
if field.typ.has_flag(.option) {
|
||||||
|
enc_name = js_enc_name(g.typ(ainfo.parent_type.set_flag(.option)))
|
||||||
|
} else {
|
||||||
enc_name = js_enc_name(g.typ(ainfo.parent_type))
|
enc_name = js_enc_name(g.typ(ainfo.parent_type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if field_sym.kind == .enum_ {
|
if field_sym.kind == .enum_ {
|
||||||
if g.is_enum_as_int(field_sym) {
|
if g.is_enum_as_int(field_sym) {
|
||||||
if field.typ.has_flag(.option) {
|
if field.typ.has_flag(.option) {
|
||||||
@ -806,7 +822,12 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}._v_unix));')
|
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}._v_unix));')
|
||||||
} else {
|
} else {
|
||||||
if !field.typ.is_any_kind_of_pointer() {
|
if !field.typ.is_any_kind_of_pointer() {
|
||||||
|
if field_sym.kind == .alias && field.typ.has_flag(.option) {
|
||||||
|
parent_type := g.table.unaliased_type(field.typ).set_flag(.option)
|
||||||
|
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(*(${g.typ(parent_type)}*)&${prefix_enc}${op}${c_name(field.name)})); /*?A*/')
|
||||||
|
} else {
|
||||||
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${prefix_enc}${op}${c_name(field.name)})); /*A*/')
|
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${prefix_enc}${op}${c_name(field.name)})); /*A*/')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
arg_prefix := if field.typ.is_ptr() { '' } else { '*' }
|
arg_prefix := if field.typ.is_ptr() { '' } else { '*' }
|
||||||
sptr_value := '${prefix_enc}${op}${c_name(field.name)}'
|
sptr_value := '${prefix_enc}${op}${c_name(field.name)}'
|
||||||
|
Loading…
Reference in New Issue
Block a user