Skip to content

Commit

Permalink
x.json2.decoder2: fix wrong sumtype and struct decoder in array (vlan…
Browse files Browse the repository at this point in the history
  • Loading branch information
enghitalo authored Dec 2, 2024
1 parent 3036a5a commit f29fb5a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 76 deletions.
96 changes: 33 additions & 63 deletions vlib/x/json2/decoder2/decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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++
}
}
`[`, `{`, `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')
// 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')
}
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] != `:` {
Expand All @@ -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')
}
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
22 changes: 22 additions & 0 deletions vlib/x/json2/decoder2/tests/decode_array_test.v
Original file line number Diff line number Diff line change
@@ -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]

Expand All @@ -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
},
]
}
25 changes: 12 additions & 13 deletions vlib/x/json2/decoder2/tests/json_sumtype_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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() {
Expand Down

0 comments on commit f29fb5a

Please sign in to comment.