diff --git a/vlib/json/tests/json_is_null_attr_test.v b/vlib/json/tests/json_is_null_attr_test.v new file mode 100644 index 00000000000000..98abc96674b316 --- /dev/null +++ b/vlib/json/tests/json_is_null_attr_test.v @@ -0,0 +1,26 @@ +import json + +struct Bar { + name ?string @[json_null] +} + +struct Foo { + name ?string @[json_null] + age ?int @[json_null] + text ?string + other ?Bar + other2 ?Bar @[json_null] +} + +fn test_main() { + assert json.encode(Foo{}) == '{"name":null,"age":null,"other2":null}' + assert json.encode(Foo{ name: '' }) == '{"name":"","age":null,"other2":null}' + assert json.encode(Foo{ age: 10 }) == '{"name":null,"age":10,"other2":null}' + assert json.encode(Foo{ + age: 10 + other2: Bar{ + name: none + } + }) == '{"name":null,"age":10,"other2":{"name":null}}' + assert json.decode(Foo, json.encode(Foo{}))! == Foo{} +} diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index 2013abb461dfea..e379385945bdf1 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -649,6 +649,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st mut is_required := false mut is_omit_empty := false mut skip_embed := false + mut is_json_null := false for attr in field.attrs { match attr.name { @@ -672,6 +673,9 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st 'omitempty' { is_omit_empty = true } + 'json_null' { + is_json_null = true + } else {} } } @@ -952,7 +956,11 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st } if is_option { - enc.writeln('\t} // !none') + if is_json_null { + enc.writeln('\t} else {') + enc.writeln('\t\tcJSON_AddItemToObject(o, "${name}", cJSON_CreateNull());') + } + enc.writeln('\t}') } } }