From 8cdb507bedad05bc516c470c6f8245a67023f8f9 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 30 Dec 2024 15:59:28 -0300 Subject: [PATCH] json: support `@[json_null]` tag to enforce `null`, when encoding `none` option values (#23319) --- vlib/json/tests/json_is_null_attr_test.v | 26 ++++++++++++++++++++++++ vlib/v/gen/c/json.v | 10 ++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 vlib/json/tests/json_is_null_attr_test.v 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 0000000000..98abc96674 --- /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 2013abb461..e379385945 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}') } } }