x.json2.decoder2: fix wrong sumtype and struct decoder in array (#23041)

This commit is contained in:
Hitalo Souza 2024-12-02 01:21:37 -04:00 committed by GitHub
parent 3036a5afc6
commit f29fb5a9f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 67 additions and 76 deletions

View file

@ -218,10 +218,6 @@ fn (mut checker Decoder) check_json_format(val string) ! {
continue continue
} }
if val[checker.checker_idx] != `"` {
checker.checker_idx++
}
// skip whitespace // skip whitespace
for val[checker.checker_idx] in [` `, `\t`, `\n`] { for val[checker.checker_idx] in [` `, `\t`, `\n`] {
if checker.checker_idx >= checker_end - 1 { if checker.checker_idx >= checker_end - 1 {
@ -234,39 +230,21 @@ fn (mut checker Decoder) check_json_format(val string) ! {
continue continue
} }
match val[checker.checker_idx] { if val[checker.checker_idx] != `"` {
`"` { return checker.error('Expecting object key')
// Object key }
checker.check_json_format(val)!
for val[checker.checker_idx] != `:` { // Object key
if checker.checker_idx >= checker_end - 1 { checker.check_json_format(val)!
return checker.error('EOF error: key colon not found')
} for val[checker.checker_idx] != `:` {
if val[checker.checker_idx] !in [` `, `\t`, `\n`] { if checker.checker_idx >= checker_end - 1 {
return checker.error('invalid value after object key') return checker.error('EOF error: key colon not found')
}
checker.checker_idx++
}
} }
`[`, `{`, `0`...`9`, `-`, `n`, `t`, `f` { if val[checker.checker_idx] !in [` `, `\t`, `\n`] {
// skip return checker.error('invalid value after object key')
}
`}` {
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')
} }
checker.checker_idx++
} }
if val[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] { match val[checker.checker_idx] {
`"`, `[`, `{`, `0`...`9`, `-`, `n`, `t`, `f` { `"`, `[`, `{`, `0`...`9`, `-`, `n`, `t`, `f` {
for val[checker.checker_idx] != `}` { checker.check_json_format(val)!
if checker.checker_idx >= checker_end - 1 { // whitespace
return checker.error('EOF error: object value not closed') for val[checker.checker_idx] in [` `, `\t`, `\n`] {
} checker.checker_idx++
checker.check_json_format(val)! }
// whitespace 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`] { for val[checker.checker_idx] in [` `, `\t`, `\n`] {
checker.checker_idx++ checker.checker_idx++
} }
if val[checker.checker_idx] != `"` {
return checker.error('Expecting object key')
}
} else {
if val[checker.checker_idx] == `}` { if val[checker.checker_idx] == `}` {
break 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 { } else {
if val[checker.checker_idx] == `}` { return checker.error('invalid object value')
break
} else {
return
}
} }
} }
} }
@ -322,9 +293,6 @@ fn (mut checker Decoder) check_json_format(val string) ! {
} }
} }
} }
if checker.checker_idx < checker_end - 2 {
checker.checker_idx++
}
} }
.array { .array {
// check if the JSON string is an empty 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 { } $else $if T.unaliased_typ is $sumtype {
decoder.decode_sumtype(mut val)! decoder.decode_sumtype(mut val)!
return
} $else $if T.unaliased_typ is time.Time { } $else $if T.unaliased_typ is time.Time {
time_info := decoder.current_node.value 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 { } $else $if T.unaliased_typ is bool {
value_info := decoder.current_node.value value_info := decoder.current_node.value

View file

@ -1,5 +1,10 @@
import x.json2.decoder2 as json import x.json2.decoder2 as json
struct StructType[T] {
mut:
val T
}
fn test_array_of_strings() { fn test_array_of_strings() {
assert json.decode[[]int]('[1, 2, 3]')! == [1, 2, 3] assert json.decode[[]int]('[1, 2, 3]')! == [1, 2, 3]
@ -25,3 +30,20 @@ fn test_array_of_strings() {
[false, true], [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
},
]
}

View file

@ -50,15 +50,14 @@ fn test_any_sum_type() {
assert json.decode[json2.Any]('1.1')! == json2.Any(f64(1.1)) 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('1'), json2.Any('2'), json2.Any('3')] assert json.decode[json2.Any]('["1", "2", "3"]')! == json2.Any([json2.Any('1'), json2.Any('2'),
// assert json.decode[json2.Any]('["1", "2", "3"]')! == json2.Any([json2.Any('1'), json2.Any('2'), json2.Any('3')])
// json2.Any('3')])
// assert json.decode[[]json2.Any]('[true, false, true]')! == [json2.Any(true), json2.Any(false), assert json.decode[[]json2.Any]('[true, false, true]')! == [json2.Any(true), json2.Any(false),
// json2.Any(true)] json2.Any(true)]
// assert json.decode[json2.Any]('[true, false, true]')! == json2.Any([json2.Any(true), json2.Any(false), assert json.decode[json2.Any]('[true, false, true]')! == json2.Any([json2.Any(true), json2.Any(false),
// json2.Any(true)]) json2.Any(true)])
assert json.decode[json2.Any]('{"hello": "world"}')! == json2.Any({ assert json.decode[json2.Any]('{"hello": "world"}')! == json2.Any({
'hello': json2.Any('world') 'hello': json2.Any('world')
@ -68,11 +67,11 @@ fn test_any_sum_type() {
'hello': json2.Any('world') 'hello': json2.Any('world')
} }
// assert json.decode[json2.Any]('{"hello1": {"hello2": "world"}}')! == json2.Any({ assert json.decode[json2.Any]('{"hello1": {"hello2": "world"}}')! == json2.Any({
// 'hello1': json2.Any({ 'hello1': json2.Any({
// 'hello2': json2.Any('world') 'hello2': json2.Any('world')
// }) })
// }) })
} }
fn test_sum_type_struct() { fn test_sum_type_struct() {