From 511274a8d498b5f2487f32a9f06bbae3ed27e06b Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 19 Jul 2023 20:33:39 -0300 Subject: [PATCH] json: fix raw decode to option string of complex data (#18902) --- vlib/json/json_option_raw_test.v | 62 ++++++++++++++++++++++++++++++++ vlib/v/gen/c/json.v | 2 +- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 vlib/json/json_option_raw_test.v diff --git a/vlib/json/json_option_raw_test.v b/vlib/json/json_option_raw_test.v new file mode 100644 index 0000000000..fae3256020 --- /dev/null +++ b/vlib/json/json_option_raw_test.v @@ -0,0 +1,62 @@ +import json + +pub struct Dto { +pub: + key string [raw] + key2 string [raw] + data ?string [raw] + optional ?string [raw] +} + +fn test_main() { + raw_json := '{ + "key": [1, 2, "test"], + "key2": { "test": 1 }, + "data": { "test": 1 }, + "optional": "test" + }' + + dto := json.decode(Dto, raw_json)! + + println(dto) + assert dto.data? == '{"test":1}' +} + +fn test_none() { + raw_json := '{ + "key": [1, 2, "test"], + "optional": "test" + }' + + dto := json.decode(Dto, raw_json)! + + println(dto) + assert dto.data == none + assert dto.optional? == '"test"' +} + +fn test_null() { + raw_json := '{ + "key": [1, 2, "test"], + "key2": null, + "data": null, + "optional": "test" + }' + + dto := json.decode(Dto, raw_json)! + + println(dto) + assert dto.key2 == 'null' + assert dto.data? == 'null' +} + +fn test_not_set() { + raw_json := '{ + }' + + dto := json.decode(Dto, raw_json)! + + println(dto) + assert dto.data == none + assert dto.optional == none +} diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index ebcb7f540d..cdaa568cb0 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -629,7 +629,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st if field.typ.has_flag(.option) { g.gen_json_for_type(field.typ) base_typ := g.base_type(field.typ) - dec.writeln('\tif (!cJSON_IsString(js_get(root, "${name}")))') + dec.writeln('\tif (js_get(root, "${name}") == NULL)') dec.writeln('\t\t_option_none(&(${base_typ}[]) { {0} }, &${prefix}${op}${c_name(field.name)}, sizeof(${base_typ}));') dec.writeln('\telse') dec.writeln('\t\t_option_ok(&(${base_typ}[]) { tos5(cJSON_PrintUnformatted(js_get(root, "${name}"))) }, &${prefix}${op}${c_name(field.name)}, sizeof(${base_typ}));')