From f29fb5a9f5e44f85056ba71a788d2f6b6dbddf1b Mon Sep 17 00:00:00 2001 From: Hitalo Souza Date: Mon, 2 Dec 2024 01:21:37 -0400 Subject: [PATCH] x.json2.decoder2: fix wrong sumtype and struct decoder in array (#23041) --- vlib/x/json2/decoder2/decode.v | 96 +++++++------------ .../json2/decoder2/tests/decode_array_test.v | 22 +++++ .../json2/decoder2/tests/json_sumtype_test.v | 25 +++-- 3 files changed, 67 insertions(+), 76 deletions(-) diff --git a/vlib/x/json2/decoder2/decode.v b/vlib/x/json2/decoder2/decode.v index 84e3a88fdd..633bfe4a36 100644 --- a/vlib/x/json2/decoder2/decode.v +++ b/vlib/x/json2/decoder2/decode.v @@ -218,10 +218,6 @@ fn (mut checker Decoder) check_json_format(val string) ! { continue } - if val[checker.checker_idx] != `"` { - checker.checker_idx++ - } - // skip whitespace for val[checker.checker_idx] in [` `, `\t`, `\n`] { if checker.checker_idx >= checker_end - 1 { @@ -234,39 +230,21 @@ fn (mut checker Decoder) check_json_format(val string) ! { continue } - match val[checker.checker_idx] { - `"` { - // Object key - checker.check_json_format(val)! + if val[checker.checker_idx] != `"` { + return checker.error('Expecting object key') + } - for val[checker.checker_idx] != `:` { - if checker.checker_idx >= checker_end - 1 { - return checker.error('EOF error: key colon not found') - } - if val[checker.checker_idx] !in [` `, `\t`, `\n`] { - return checker.error('invalid value after object key') - } - checker.checker_idx++ - } + // Object key + checker.check_json_format(val)! + + for val[checker.checker_idx] != `:` { + if checker.checker_idx >= checker_end - 1 { + return checker.error('EOF error: key colon not found') } - `[`, `{`, `0`...`9`, `-`, `n`, `t`, `f` { - // skip - } - `}` { - return - } - `]` { - return checker.error('Expecting key. Found closing bracket') - } - `,` { - return checker.error('invalid object key') - } - `:` { - return checker.error('empty object key') - } - else { - return checker.error('`${[val[checker.checker_idx]].bytestr()}` is an invalid object key') + if val[checker.checker_idx] !in [` `, `\t`, `\n`] { + return checker.error('invalid value after object key') } + checker.checker_idx++ } if val[checker.checker_idx] != `:` { @@ -282,38 +260,31 @@ fn (mut checker Decoder) check_json_format(val string) ! { match val[checker.checker_idx] { `"`, `[`, `{`, `0`...`9`, `-`, `n`, `t`, `f` { - for val[checker.checker_idx] != `}` { - if checker.checker_idx >= checker_end - 1 { - return checker.error('EOF error: object value not closed') - } - checker.check_json_format(val)! - // whitespace + checker.check_json_format(val)! + // whitespace + for val[checker.checker_idx] in [` `, `\t`, `\n`] { + checker.checker_idx++ + } + if val[checker.checker_idx] == `}` { + break + } + if checker.checker_idx >= checker_end - 1 { + return checker.error('EOF error: braces are not closed') + } + + if val[checker.checker_idx] == `,` { + checker.checker_idx++ for val[checker.checker_idx] in [` `, `\t`, `\n`] { checker.checker_idx++ } + if val[checker.checker_idx] != `"` { + return checker.error('Expecting object key') + } + } else { if val[checker.checker_idx] == `}` { break - } - if checker.checker_idx >= checker_end - 1 { - return checker.error('EOF error: braces are not closed') - } - - if val[checker.checker_idx] == `,` { - checker.checker_idx++ - for val[checker.checker_idx] in [` `, `\t`, `\n`] { - checker.checker_idx++ - } - if val[checker.checker_idx] != `"` { - return checker.error('Expecting object key') - } else { - break - } } else { - if val[checker.checker_idx] == `}` { - break - } else { - return - } + return checker.error('invalid object value') } } } @@ -322,9 +293,6 @@ fn (mut checker Decoder) check_json_format(val string) ! { } } } - if checker.checker_idx < checker_end - 2 { - checker.checker_idx++ - } } .array { // check if the JSON string is an empty array @@ -608,6 +576,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! { } } $else $if T.unaliased_typ is $sumtype { decoder.decode_sumtype(mut val)! + return } $else $if T.unaliased_typ is time.Time { time_info := decoder.current_node.value @@ -667,6 +636,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! { } } } + return } $else $if T.unaliased_typ is bool { value_info := decoder.current_node.value diff --git a/vlib/x/json2/decoder2/tests/decode_array_test.v b/vlib/x/json2/decoder2/tests/decode_array_test.v index 58d2b3229d..87caa6378c 100644 --- a/vlib/x/json2/decoder2/tests/decode_array_test.v +++ b/vlib/x/json2/decoder2/tests/decode_array_test.v @@ -1,5 +1,10 @@ import x.json2.decoder2 as json +struct StructType[T] { +mut: + val T +} + fn test_array_of_strings() { assert json.decode[[]int]('[1, 2, 3]')! == [1, 2, 3] @@ -25,3 +30,20 @@ fn test_array_of_strings() { [false, true], ] } + +fn test_array_of_struct() { + assert json.decode[[]StructType[int]]('[{"val": 1}, {"val": 2}, {"val": 3}, {"val": 4}]')! == [ + StructType{ + val: 1 + }, + StructType{ + val: 2 + }, + StructType{ + val: 3 + }, + StructType{ + val: 4 + }, + ] +} diff --git a/vlib/x/json2/decoder2/tests/json_sumtype_test.v b/vlib/x/json2/decoder2/tests/json_sumtype_test.v index 27e956525a..6463dc56b2 100644 --- a/vlib/x/json2/decoder2/tests/json_sumtype_test.v +++ b/vlib/x/json2/decoder2/tests/json_sumtype_test.v @@ -50,15 +50,14 @@ fn test_any_sum_type() { assert json.decode[json2.Any]('1.1')! == json2.Any(f64(1.1)) - // Uncomment this when #22693 is fixed - // assert json.decode[[]json2.Any]('["1", "2", "3"]')! == [json2.Any('1'), json2.Any('2'), json2.Any('3')] - // assert json.decode[json2.Any]('["1", "2", "3"]')! == json2.Any([json2.Any('1'), json2.Any('2'), - // json2.Any('3')]) + assert json.decode[[]json2.Any]('["1", "2", "3"]')! == [json2.Any('1'), json2.Any('2'), json2.Any('3')] + assert json.decode[json2.Any]('["1", "2", "3"]')! == json2.Any([json2.Any('1'), json2.Any('2'), + json2.Any('3')]) - // assert json.decode[[]json2.Any]('[true, false, true]')! == [json2.Any(true), json2.Any(false), - // json2.Any(true)] - // assert json.decode[json2.Any]('[true, false, true]')! == json2.Any([json2.Any(true), json2.Any(false), - // json2.Any(true)]) + assert json.decode[[]json2.Any]('[true, false, true]')! == [json2.Any(true), json2.Any(false), + json2.Any(true)] + assert json.decode[json2.Any]('[true, false, true]')! == json2.Any([json2.Any(true), json2.Any(false), + json2.Any(true)]) assert json.decode[json2.Any]('{"hello": "world"}')! == json2.Any({ 'hello': json2.Any('world') @@ -68,11 +67,11 @@ fn test_any_sum_type() { 'hello': json2.Any('world') } - // assert json.decode[json2.Any]('{"hello1": {"hello2": "world"}}')! == json2.Any({ - // 'hello1': json2.Any({ - // 'hello2': json2.Any('world') - // }) - // }) + assert json.decode[json2.Any]('{"hello1": {"hello2": "world"}}')! == json2.Any({ + 'hello1': json2.Any({ + 'hello2': json2.Any('world') + }) + }) } fn test_sum_type_struct() {