diff --git a/vlib/json/json_raw_test.v b/vlib/json/json_raw_test.v new file mode 100644 index 0000000000..812d14fe0b --- /dev/null +++ b/vlib/json/json_raw_test.v @@ -0,0 +1,38 @@ +import json + +struct TestOptionalRawString { + id int + data ?string [raw] +} + +fn test_raw_opt() { + test := TestOptionalRawString{ + id: 1 + data: 't +e +s +t' + } + encoded := json.encode(test) + assert json.decode(TestOptionalRawString, encoded)!.data? == r'"t\ne\ns\nt"' +} + +fn test_raw_none() { + test := TestOptionalRawString{ + id: 1 + data: none + } + encoded := json.encode(test) + r := json.decode(TestOptionalRawString, encoded)!.data + assert r == none +} + +fn test_raw_empty_string() { + test := TestOptionalRawString{ + id: 1 + data: '' + } + encoded := json.encode(test) + r := json.decode(TestOptionalRawString, encoded)!.data or { 'z' } + assert r == '""' +} diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index 2bdd4b71a9..4343cf59ab 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -534,8 +534,17 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st prefix := if utyp.has_flag(.option) { '(*(${g.base_type(utyp)}*)res.data)' } else { 'res' } // First generate decoding if is_raw { - dec.writeln('\tres${op}${c_name(field.name)} = tos5(cJSON_PrintUnformatted(' + - 'js_get(root, "${name}")));') + 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('\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}));') + } else { + dec.writeln('\tres${op}${c_name(field.name)} = tos5(cJSON_PrintUnformatted(' + + 'js_get(root, "${name}")));') + } } else { // Now generate decoders for all field types in this struct // need to do it here so that these functions are generated first