From 87320f8f934a81e1d7a6feb7f963cd222dc9fde4 Mon Sep 17 00:00:00 2001 From: johnpgr <62309738+johnpgr@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:55:02 -0300 Subject: [PATCH] x.json2: fix encoder commas (#20916) --- vlib/x/json2/encoder.v | 26 ++-- .../encode_struct_skippable_fields_test.v | 134 ++++++++++++++++++ vlib/x/json2/tests/encode_struct_test.v | 47 ------ 3 files changed, 150 insertions(+), 57 deletions(-) create mode 100644 vlib/x/json2/tests/encode_struct_skippable_fields_test.v diff --git a/vlib/x/json2/encoder.v b/vlib/x/json2/encoder.v index b95ebaf990b52d..5f6701acb0a43e 100644 --- a/vlib/x/json2/encoder.v +++ b/vlib/x/json2/encoder.v @@ -177,17 +177,27 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut buf []u8) ! { mut fields_len := 0 $for field in U.fields { - $if field.is_option { - if val.$(field.name) != none { + mut @continue := false + for attr in field.attrs { + if attr.contains('json: ') { + if attr.replace('json: ', '') == '-' { + @continue = true + } + break + } + } + if !@continue { + $if field.is_option { + if val.$(field.name) != none { + fields_len++ + } + } $else { fields_len++ } - } $else { - fields_len++ } } $for field in U.fields { mut ignore_field := false - mut skip_field := false value := val.$(field.name) @@ -200,16 +210,12 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut buf []u8) ! { json_name = attr.replace('json: ', '') if json_name == '-' { ignore_field = true - skip_field = true } break } } - if skip_field { - i++ - fields_len-- - } else { + if !ignore_field { $if value is $option { workaround := val.$(field.name) if workaround != none { // smartcast diff --git a/vlib/x/json2/tests/encode_struct_skippable_fields_test.v b/vlib/x/json2/tests/encode_struct_skippable_fields_test.v new file mode 100644 index 00000000000000..cf329677a3593a --- /dev/null +++ b/vlib/x/json2/tests/encode_struct_skippable_fields_test.v @@ -0,0 +1,134 @@ +import time +import x.json2 as json + +struct StructTypeSkippedFields[T] { +mut: + val T @[json: '-'] + val1 T + val2 T @[json: '-'] + val3 T +} + +struct StructTypeSkippedFields1[T] { +mut: + val T + val1 T @[json: '-'] + val2 T + val3 T @[json: '-'] +} + +struct StructTypeSkippedFields2[T] { +mut: + val T @[json: '-'] + val1 T @[json: '-'] + val2 T @[json: '-'] + val3 T @[json: '-'] +} + +struct StructTypeSkippedFields3[T, U, V] { +mut: + val T @[json: '-'] + val1 U + val2 V + val3 T @[json: '-'] +} + +struct StructTypeSkippedFields4 { +mut: + val string @[json: '-'] + val1 i64 + val2 f64 + val3 time.Time +} + +struct StructTypeSkippedFields5 { +mut: + val string @[json: '-'] + val1 i64 @[json: '-'] + val2 f64 + val3 time.Time +} + +struct StructTypeSkippedFields6 { +mut: + val string @[json: '-'] + val1 i64 + val2 f64 @[json: '-'] + val3 time.Time +} + +struct StructTypeSkippedFields7 { +mut: + val string + val1 i64 @[json: '-'] + val2 f64 @[json: '-'] + val3 time.Time +} + +struct StructTypeSkippedFields8 { +mut: + val string + val1 i64 @[json: '-'] + val2 f64 + val3 time.Time @[json: '-'] +} + +fn test_encode_struct_skipped_fields() { + assert json.encode(StructTypeSkippedFields[string]{ + val: 'string_val' + val1: 'string_val1' + val2: 'string_val2' + val3: 'string_val3' + }) == '{"val1":"string_val1","val3":"string_val3"}' + + assert json.encode(StructTypeSkippedFields1[string]{ + val: 'string_val' + val1: 'string_val1' + val2: 'string_val2' + val3: 'string_val3' + }) == '{"val":"string_val","val2":"string_val2"}' + + assert json.encode(StructTypeSkippedFields2[string]{ + val: 'string_val' + val1: 'string_val1' + val2: 'string_val2' + val3: 'string_val3' + }) == '{}' + + assert json.encode(StructTypeSkippedFields3[string, i64, f64]{ + val: 'string_val' + val1: 1 + val2: 1.0 + val3: 'string_val' + }) == '{"val1":1,"val2":1.0}' + + assert json.encode(StructTypeSkippedFields4{ + val: 'string_val' + val1: 1 + val2: 1.0 + }) == '{"val1":1,"val2":1.0,"val3":"0000-00-00T00:00:00.000Z"}' + + assert json.encode(StructTypeSkippedFields5{ + val: 'string_val' + val1: 1 + val2: 1.0 + }) == '{"val2":1.0,"val3":"0000-00-00T00:00:00.000Z"}' + + assert json.encode(StructTypeSkippedFields6{ + val: 'string_val' + val1: 1 + val2: 1.0 + }) == '{"val1":1,"val3":"0000-00-00T00:00:00.000Z"}' + + assert json.encode(StructTypeSkippedFields7{ + val: 'string_val' + val1: 1 + val2: 1.0 + }) == '{"val":"string_val","val3":"0000-00-00T00:00:00.000Z"}' + + assert json.encode(StructTypeSkippedFields8{ + val: 'string_val' + val1: 1 + val2: 1.0 + }) == '{"val":"string_val","val2":1.0}' +} diff --git a/vlib/x/json2/tests/encode_struct_test.v b/vlib/x/json2/tests/encode_struct_test.v index f06a569cbc7340..7c4f782a8eac5d 100644 --- a/vlib/x/json2/tests/encode_struct_test.v +++ b/vlib/x/json2/tests/encode_struct_test.v @@ -44,30 +44,6 @@ mut: val &T } -struct StructTypeSkippedFields[T] { -mut: - val T @[json: '-'] - val1 T - val2 T @[json: '-'] - val3 T -} - -struct StructTypeSkippedFields2[T] { -mut: - val T - val1 T @[json: '-'] - val2 T - val3 T @[json: '-'] -} - -struct StructTypeSkippedFields3[T] { -mut: - val T @[json: '-'] - val1 T @[json: '-'] - val2 T @[json: '-'] - val3 T @[json: '-'] -} - fn test_types() { assert json.encode(StructType[string]{}) == '{"val":""}' assert json.encode(StructType[string]{ val: '' }) == '{"val":""}' @@ -235,29 +211,6 @@ fn test_option_array() { // }) == '{"val":[[0,1],[0,2,3],[2],[5,1]]}' } -fn test_skipped_fields() { - assert json.encode(StructTypeSkippedFields[string]{ - val: '' - val1: '' - val2: '' - val3: '' - }) == '{"val1":"","val3":""}' - - assert json.encode(StructTypeSkippedFields2[string]{ - val: '' - val1: '' - val2: '' - val3: '' - }) == '{"val":"","val2":""}' - - assert json.encode(StructTypeSkippedFields3[string]{ - val: '' - val1: '' - val2: '' - val3: '' - }) == '{}' -} - fn test_alias() { assert json.encode(StructType[StringAlias]{}) == '{"val":""}' assert json.encode(StructType[StringAlias]{ val: '' }) == '{"val":""}'