mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
json: fix option sumtype handling (#20186)
This commit is contained in:
parent
d474f6901d
commit
db6ae6ee9b
57
vlib/json/json_sumtype_test.v
Normal file
57
vlib/json/json_sumtype_test.v
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
type Prices = Price | []Price
|
||||||
|
|
||||||
|
pub struct ShopResponseData {
|
||||||
|
attributes Attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Attributes {
|
||||||
|
price ?Prices
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Price {
|
||||||
|
net f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
data := '{"attributes": {"price": [{"net": 1, "_type": "Price"}, {"net": 2, "_type": "Price"}]}}'
|
||||||
|
entity := json.decode(ShopResponseData, data) or { panic(err) }
|
||||||
|
assert entity == ShopResponseData{
|
||||||
|
attributes: Attributes{
|
||||||
|
price: Prices([Price{
|
||||||
|
net: 1
|
||||||
|
}, Price{
|
||||||
|
net: 2
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data2 := '{"attributes": {"price": {"net": 1, "_type": "Price"}}}'
|
||||||
|
entity2 := json.decode(ShopResponseData, data2) or { panic(err) }
|
||||||
|
assert entity2 == ShopResponseData{
|
||||||
|
attributes: Attributes{
|
||||||
|
price: Prices(Price{
|
||||||
|
net: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data3 := json.encode(ShopResponseData{
|
||||||
|
attributes: Attributes{
|
||||||
|
price: Prices([Price{
|
||||||
|
net: 1.2
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
assert data3 == '{"attributes":{"price":[{"net":1.2,"_type":"Price"}]}}'
|
||||||
|
|
||||||
|
entity3 := json.decode(ShopResponseData, data3) or { panic(err) }
|
||||||
|
assert entity3 == ShopResponseData{
|
||||||
|
attributes: Attributes{
|
||||||
|
price: Prices([Price{
|
||||||
|
net: 1.2
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -364,8 +364,8 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
|
|||||||
// DECODING (inline)
|
// DECODING (inline)
|
||||||
$if !json_no_inline_sumtypes ? {
|
$if !json_no_inline_sumtypes ? {
|
||||||
type_tmp := g.new_tmp_var()
|
type_tmp := g.new_tmp_var()
|
||||||
dec.writeln('\tif (cJSON_IsObject(root)) {')
|
dec.writeln('\tif (cJSON_IsObject(root) || (cJSON_IsArray(root) && cJSON_IsObject(root->child))) {')
|
||||||
dec.writeln('\t\tcJSON* ${type_tmp} = js_get(root, "_type");')
|
dec.writeln('\t\tcJSON* ${type_tmp} = cJSON_IsObject(root) ? js_get(root, "_type") : js_get(root->child, "_type");')
|
||||||
dec.writeln('\t\tif (${type_tmp} != 0) {')
|
dec.writeln('\t\tif (${type_tmp} != 0) {')
|
||||||
dec.writeln('\t\t\tchar* ${type_var} = cJSON_GetStringValue(${type_tmp});')
|
dec.writeln('\t\t\tchar* ${type_var} = cJSON_GetStringValue(${type_tmp});')
|
||||||
// dec.writeln('\t\t\tcJSON_DeleteItemFromObjectCaseSensitive(root, "_type");')
|
// dec.writeln('\t\t\tcJSON_DeleteItemFromObjectCaseSensitive(root, "_type");')
|
||||||
@ -391,11 +391,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
|
|||||||
g.definitions.writeln('static inline ${sym.cname} ${variant_typ}_to_sumtype_${sym.cname}(${variant_typ}* x);')
|
g.definitions.writeln('static inline ${sym.cname} ${variant_typ}_to_sumtype_${sym.cname}(${variant_typ}* x);')
|
||||||
|
|
||||||
// ENCODING
|
// ENCODING
|
||||||
if is_option {
|
enc.writeln('\tif (${var_data}${field_op}_typ == ${variant.idx()}) {')
|
||||||
enc.writeln('\tif (${var_data}${field_op}_typ == ${variant.idx()}) {')
|
|
||||||
} else {
|
|
||||||
enc.writeln('\tif (val${field_op}_typ == ${variant.idx()}) {')
|
|
||||||
}
|
|
||||||
$if json_no_inline_sumtypes ? {
|
$if json_no_inline_sumtypes ? {
|
||||||
if variant_sym.kind == .enum_ {
|
if variant_sym.kind == .enum_ {
|
||||||
enc.writeln('\t\tcJSON_AddItemToObject(o, "${unmangled_variant_name}", ${js_enc_name('u64')}(*${var_data}${field_op}_${variant_typ}));')
|
enc.writeln('\t\tcJSON_AddItemToObject(o, "${unmangled_variant_name}", ${js_enc_name('u64')}(*${var_data}${field_op}_${variant_typ}));')
|
||||||
@ -425,10 +421,16 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
|
|||||||
}
|
}
|
||||||
} else if variant_sym.name == 'time.Time' {
|
} else if variant_sym.name == 'time.Time' {
|
||||||
enc.writeln('\t\tcJSON_AddItemToObject(o, "_type", cJSON_CreateString("${unmangled_variant_name}"));')
|
enc.writeln('\t\tcJSON_AddItemToObject(o, "_type", cJSON_CreateString("${unmangled_variant_name}"));')
|
||||||
enc.writeln('\t\tcJSON_AddItemToObject(o, "value", ${js_enc_name('i64')}(val${field_op}_${variant_typ}->__v_unix));')
|
enc.writeln('\t\tcJSON_AddItemToObject(o, "value", ${js_enc_name('i64')}(${var_data}${field_op}_${variant_typ}->__v_unix));')
|
||||||
} else {
|
} else {
|
||||||
enc.writeln('\t\to = ${js_enc_name(variant_typ)}(*val${field_op}_${variant_typ});')
|
enc.writeln('\t\to = ${js_enc_name(variant_typ)}(*${var_data}${field_op}_${variant_typ});')
|
||||||
enc.writeln('\t\tcJSON_AddItemToObject(o, "_type", cJSON_CreateString("${unmangled_variant_name}"));')
|
if variant_sym.kind == .array {
|
||||||
|
enc.writeln('\t\tif (cJSON_IsObject(o->child)) {')
|
||||||
|
enc.writeln('\t\t\tcJSON_AddItemToObject(o->child, "_type", cJSON_CreateString("${unmangled_variant_name}"));')
|
||||||
|
enc.writeln('\t\t}')
|
||||||
|
} else {
|
||||||
|
enc.writeln('\t\tcJSON_AddItemToObject(o, "_type", cJSON_CreateString("${unmangled_variant_name}"));')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enc.writeln('\t}')
|
enc.writeln('\t}')
|
||||||
@ -474,13 +476,17 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
|
|||||||
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}(&${tmp});')
|
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}(&${tmp});')
|
||||||
dec.writeln('\t\t\t}')
|
dec.writeln('\t\t\t}')
|
||||||
} else if !is_js_prim(variant_typ) && variant_sym.kind != .enum_ {
|
} else if !is_js_prim(variant_typ) && variant_sym.kind != .enum_ {
|
||||||
dec.writeln('\t\t\tif (strcmp("${unmangled_variant_name}", ${type_var}) == 0) {')
|
dec.writeln('\t\t\tif (strcmp("${unmangled_variant_name}", ${type_var}) == 0 && ${variant_sym.kind == .array} == cJSON_IsArray(root)) {')
|
||||||
dec.writeln('\t\t\t\t${result_name}_${variant_typ} ${tmp} = ${js_dec_name(variant_typ)}(root);')
|
dec.writeln('\t\t\t\t${result_name}_${variant_typ} ${tmp} = ${js_dec_name(variant_typ)}(root);')
|
||||||
dec.writeln('\t\t\t\tif (${tmp}.is_error) {')
|
dec.writeln('\t\t\t\tif (${tmp}.is_error) {')
|
||||||
|
|
||||||
dec.writeln('\t\t\t\t\treturn (${result_name}_${ret_styp}){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
|
dec.writeln('\t\t\t\t\treturn (${result_name}_${ret_styp}){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
|
||||||
dec.writeln('\t\t\t\t}')
|
dec.writeln('\t\t\t\t}')
|
||||||
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}((${variant_typ}*)${tmp}.data);')
|
if is_option {
|
||||||
|
dec.writeln('\t\t\t\t_option_ok(&(${sym.cname}[]){ ${variant_typ}_to_sumtype_${sym.cname}((${variant_typ}*)${tmp}.data) }, (${option_name}*)&res, sizeof(${sym.cname}));')
|
||||||
|
} else {
|
||||||
|
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}((${variant_typ}*)${tmp}.data);')
|
||||||
|
}
|
||||||
dec.writeln('\t\t\t}')
|
dec.writeln('\t\t\t}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -546,15 +552,21 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
|
|||||||
'cJSON_IsString(root->child)'
|
'cJSON_IsString(root->child)'
|
||||||
} else if var_t.ends_with('bool') {
|
} else if var_t.ends_with('bool') {
|
||||||
'cJSON_IsBool(root->child)'
|
'cJSON_IsBool(root->child)'
|
||||||
|
} else if g.table.sym(g.table.value_type(ast.Type(variant_symbols[i].idx))).kind == .struct_ {
|
||||||
|
'cJSON_IsObject(root->child)'
|
||||||
} else {
|
} else {
|
||||||
'cJSON_IsNumber(root->child)'
|
'cJSON_IsNumber(root->child)'
|
||||||
}
|
}
|
||||||
dec.writeln('\t\tif (cJSON_IsArray(root) && ${judge_elem_typ}) {')
|
dec.writeln('\t\tif (cJSON_IsArray(root) && ${judge_elem_typ}) {')
|
||||||
dec.writeln('\t\t\t${result_name}_${var_t} ${tmp} = ${js_dec_name(var_t)}(root);')
|
dec.writeln('\t\t\t${result_name}_${var_t} ${tmp} = ${js_dec_name(var_t)}(root);')
|
||||||
dec.writeln('\t\t\tif (${tmp}.is_error) {')
|
dec.writeln('\t\t\tif (${tmp}.is_error) {')
|
||||||
dec.writeln('\t\t\t\treturn (${result_name}_${sym.cname}){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
|
dec.writeln('\t\t\t\treturn (${result_name}_${ret_styp}){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
|
||||||
dec.writeln('\t\t\t}')
|
dec.writeln('\t\t\t}')
|
||||||
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}((${var_t}*)${tmp}.data);')
|
if utyp.has_flag(.option) {
|
||||||
|
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}((${var_t}*)${tmp}.data) }, &${prefix}res, sizeof(${sym.cname}));')
|
||||||
|
} else {
|
||||||
|
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}((${var_t}*)${tmp}.data);')
|
||||||
|
}
|
||||||
dec.writeln('\t\t}')
|
dec.writeln('\t\t}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user