mirror of
https://github.com/vlang/v.git
synced 2025-09-10 16:00:31 -04:00
json: fix json encode/decode with embed support (#22277)
This commit is contained in:
parent
3ec4939506
commit
1233858488
31
vlib/json/json_embed_test.v
Normal file
31
vlib/json/json_embed_test.v
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
struct Json3 {
|
||||||
|
embed f64
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Json2 {
|
||||||
|
Json3
|
||||||
|
inner []f64
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Json {
|
||||||
|
Json2
|
||||||
|
test f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
str := '{"inner": [1, 2, 3, 4, 5],"test": 1.0, "embed": 2.0}'
|
||||||
|
data := json.decode(Json, str) or {
|
||||||
|
eprintln('Failed to decode json, error: ${err}')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
println(data)
|
||||||
|
assert data.inner.len == 5
|
||||||
|
assert data.inner[0] == 1.0
|
||||||
|
assert data.inner[4] == 5.0
|
||||||
|
assert data.test == 1.0
|
||||||
|
assert data.embed == 2.0
|
||||||
|
|
||||||
|
assert dump(json.encode(data)) == '{"embed":2,"inner":[1,2,3,4,5],"test":1}'
|
||||||
|
}
|
27
vlib/json/json_encode_embed_test.v
Normal file
27
vlib/json/json_encode_embed_test.v
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
struct Json2 {
|
||||||
|
inner []f64
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Json {
|
||||||
|
Json2
|
||||||
|
test f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
str := '{"inner":[1,2,3,4,5],"test":1.2}'
|
||||||
|
data := json.decode(Json, str) or {
|
||||||
|
eprintln('Failed to decode json, error: ${err}')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
println(data)
|
||||||
|
assert data.inner.len == 5
|
||||||
|
assert data.inner[0] == 1.0
|
||||||
|
assert data.inner[4] == 5.0
|
||||||
|
assert data.test == 1.2
|
||||||
|
|
||||||
|
data_json := json.encode(data)
|
||||||
|
dump(data_json)
|
||||||
|
assert data_json == str
|
||||||
|
}
|
@ -614,6 +614,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
mut is_skip := false
|
mut is_skip := false
|
||||||
mut is_required := false
|
mut is_required := false
|
||||||
mut is_omit_empty := false
|
mut is_omit_empty := false
|
||||||
|
mut skip_embed := false
|
||||||
|
|
||||||
for attr in field.attrs {
|
for attr in field.attrs {
|
||||||
match attr.name {
|
match attr.name {
|
||||||
@ -766,12 +767,17 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
if name.len > 0 && name[0].is_capital() && field_sym.info is ast.Struct {
|
if name.len > 0 && name[0].is_capital() && field_sym.info is ast.Struct {
|
||||||
for embed in info.embeds {
|
for embed in info.embeds {
|
||||||
if embed == int(field.typ) {
|
if embed == int(field.typ) {
|
||||||
|
prefix_embed := if embed_prefix != '' {
|
||||||
|
'${embed_prefix}.${name}'
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
}
|
||||||
g.gen_struct_enc_dec(field.typ, g.table.sym(field.typ).info,
|
g.gen_struct_enc_dec(field.typ, g.table.sym(field.typ).info,
|
||||||
styp, mut enc, mut dec, name)
|
styp, mut enc, mut dec, prefix_embed)
|
||||||
|
skip_embed = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
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)
|
||||||
@ -797,15 +803,15 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
|||||||
dec.writeln('\t}')
|
dec.writeln('\t}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if embed_prefix.len > 0 {
|
if skip_embed {
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
// Encoding
|
// Encoding
|
||||||
mut enc_name := js_enc_name(field_type)
|
mut enc_name := js_enc_name(field_type)
|
||||||
prefix_enc := if utyp.has_flag(.option) {
|
prefix_enc := if utyp.has_flag(.option) {
|
||||||
'(*(${g.base_type(utyp)}*)val.data)'
|
'(*(${g.base_type(utyp)}*)val${embed_member}.data)'
|
||||||
} else {
|
} else {
|
||||||
'val'
|
'val${embed_member}'
|
||||||
}
|
}
|
||||||
is_option := field.typ.has_flag(.option)
|
is_option := field.typ.has_flag(.option)
|
||||||
indent := if is_option { '\t\t' } else { '\t' }
|
indent := if is_option { '\t\t' } else { '\t' }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user