Skip to content

Commit cd6cc65

Browse files
authored
json: fix [omitempty] with string (#17813)
1 parent 57aa4de commit cd6cc65

File tree

2 files changed

+51
-19
lines changed

2 files changed

+51
-19
lines changed

vlib/json/json_omitempty_test.v

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import json
2+
3+
pub struct MyStruct {
4+
pub mut:
5+
code int
6+
message string
7+
data string [omitempty]
8+
data2 ?string [omitempty]
9+
}
10+
11+
fn test_simple() {
12+
obj := MyStruct{
13+
code: 1
14+
message: 'yes'
15+
data2: 'a'
16+
}
17+
assert dump(json.encode(obj)) == '{"code":1,"message":"yes","data2":"a"}'
18+
}
19+
20+
fn test_none() {
21+
obj := MyStruct{
22+
code: 1
23+
}
24+
assert dump(json.encode(obj)) == '{"code":1,"message":""}'
25+
}

vlib/v/gen/c/json.v

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -648,11 +648,18 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
648648
'val'
649649
}
650650
is_option := field.typ.has_flag(.option)
651+
indent := if is_option { '\t\t' } else { '\t' }
651652
if is_option {
652653
enc.writeln('\tif (val${op}${c_name(field.name)}.state != 2) {')
653654
}
654655
if is_omit_empty {
655-
enc.writeln('\t if (val${op}${c_name(field.name)} != ${g.type_default(field.typ)})')
656+
if field.typ.has_flag(.option) {
657+
enc.writeln('${indent}if (val${op}${c_name(field.name)}.state != 2)')
658+
} else if field.typ == ast.string_type {
659+
enc.writeln('${indent}if (val${op}${c_name(field.name)}.len != 0)')
660+
} else {
661+
enc.writeln('${indent}if (val${op}${c_name(field.name)} != ${g.type_default(field.typ)})')
662+
}
656663
}
657664
if !is_js_prim(field_type) {
658665
if field_sym.kind == .alias {
@@ -663,44 +670,44 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
663670
if field_sym.kind == .enum_ {
664671
if g.is_enum_as_int(field_sym) {
665672
if field.typ.has_flag(.option) {
666-
enc.writeln('\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(*${prefix_enc}${op}${c_name(field.name)}.data));\n')
673+
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(*${prefix_enc}${op}${c_name(field.name)}.data));\n')
667674
} else {
668-
enc.writeln('\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}));\n')
675+
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}));\n')
669676
}
670677
} else {
671678
if field.typ.has_flag(.option) {
672-
enc.writeln('\t{')
673-
enc.writeln('\t\tcJSON *enum_val;')
679+
enc.writeln('${indent}\t{')
680+
enc.writeln('${indent}\t\tcJSON *enum_val;')
674681
g.gen_enum_to_str(field.typ, field_sym, '*(${g.base_type(field.typ)}*)${prefix_enc}${op}${c_name(field.name)}.data',
675-
'enum_val', '\t\t', mut enc)
676-
enc.writeln('\t\tcJSON_AddItemToObject(o, "${name}", enum_val);')
677-
enc.writeln('\t}')
682+
'enum_val', '${indent}\t\t', mut enc)
683+
enc.writeln('${indent}\t\tcJSON_AddItemToObject(o, "${name}", enum_val);')
684+
enc.writeln('${indent}\t}')
678685
} else {
679-
enc.writeln('\t{')
680-
enc.writeln('\t\tcJSON *enum_val;')
686+
enc.writeln('${indent}\t{')
687+
enc.writeln('${indent}\t\tcJSON *enum_val;')
681688
g.gen_enum_to_str(field.typ, field_sym, '${prefix_enc}${op}${c_name(field.name)}',
682-
'enum_val', '\t\t', mut enc)
683-
enc.writeln('\t\tcJSON_AddItemToObject(o, "${name}", enum_val);')
684-
enc.writeln('\t}')
689+
'enum_val', '${indent}\t\t', mut enc)
690+
enc.writeln('${indent}\t\tcJSON_AddItemToObject(o, "${name}", enum_val);')
691+
enc.writeln('${indent}\t}')
685692
}
686693
}
687694
} else {
688695
if field_sym.name == 'time.Time' {
689696
// time struct requires special treatment
690697
// it has to be encoded as a unix timestamp number
691-
enc.writeln('\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}._v_unix));')
698+
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}._v_unix));')
692699
} else {
693700
if !field.typ.is_real_pointer() {
694-
enc.writeln('\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${prefix_enc}${op}${c_name(field.name)})); /*A*/')
701+
enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${prefix_enc}${op}${c_name(field.name)})); /*A*/')
695702
} else {
696703
arg_prefix := if field.typ.is_ptr() { '' } else { '*' }
697704
sptr_value := '${prefix_enc}${op}${c_name(field.name)}'
698705
if !field.typ.has_flag(.option) {
699-
enc.writeln('\tif (${sptr_value} != 0) {')
700-
enc.writeln('\t\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${arg_prefix}${sptr_value}));')
701-
enc.writeln('\t}\n')
706+
enc.writeln('${indent}\tif (${sptr_value} != 0) {')
707+
enc.writeln('${indent}\t\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${arg_prefix}${sptr_value}));')
708+
enc.writeln('${indent}\t}\n')
702709
} else {
703-
enc.writeln('\t\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${arg_prefix}${sptr_value}));')
710+
enc.writeln('${indent}\t\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${arg_prefix}${sptr_value}));')
704711
}
705712
}
706713
}

0 commit comments

Comments
 (0)