Skip to content

Commit a11de72

Browse files
authored
decoder2: improve checker with better EOF detection (#25075)
1 parent 9140c9f commit a11de72

File tree

9 files changed

+139
-229
lines changed

9 files changed

+139
-229
lines changed

vlib/x/json2/decoder2/check.v

Lines changed: 76 additions & 206 deletions
Large diffs are not rendered by default.

vlib/x/json2/decoder2/decode.v

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ fn (list &LinkedList[T]) free() {
126126
enum ValueKind {
127127
array
128128
object
129-
string_
129+
string
130130
number
131131
boolean
132132
null
@@ -316,7 +316,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
316316
$if val is StringDecoder {
317317
struct_info := decoder.current_node.value
318318

319-
if struct_info.value_kind == .string_ {
319+
if struct_info.value_kind == .string {
320320
val.from_json_string(decoder.json[struct_info.position + 1..struct_info.position +
321321
struct_info.length - 1]) or {
322322
decoder.decode_error('${typeof(*val).name}: ${err.msg()}')!
@@ -370,7 +370,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
370370
$if T.unaliased_typ is string {
371371
string_info := decoder.current_node.value
372372

373-
if string_info.value_kind == .string_ {
373+
if string_info.value_kind == .string {
374374
mut string_buffer := []u8{cap: string_info.length} // might be too long but most json strings don't contain many escape characters anyways
375375

376376
mut buffer_index := 1
@@ -542,7 +542,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
542542
current_field_info = current_field_info.next
543543
continue
544544
}
545-
.string_ {
545+
.string {
546546
if decoder.current_node.next.value.length == 2 {
547547
current_field_info = current_field_info.next
548548
continue
@@ -705,7 +705,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
705705

706706
if value_info.value_kind == .number {
707707
unsafe { decoder.decode_number(&val)! }
708-
} else if value_info.value_kind == .string_ {
708+
} else if value_info.value_kind == .string {
709709
// recheck if string contains number
710710
decoder.checker_idx = value_info.position + 1
711711
decoder.check_number()!

vlib/x/json2/decoder2/decode_sumtype.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fn (mut decoder Decoder) check_element_type_valid[T](element T, current_node &No
4242
}
4343

4444
match current_node.value.value_kind {
45-
.string_ {
45+
.string {
4646
$if element is string {
4747
return true
4848
} $else $if element is time.Time {
@@ -220,7 +220,7 @@ fn (mut decoder Decoder) init_sumtype_by_value_kind[T](mut val T, value_info Val
220220
mut failed_struct := false
221221

222222
match value_info.value_kind {
223-
.string_ {
223+
.string {
224224
$for v in val.variants {
225225
$if v.typ is string {
226226
val = T(v)

vlib/x/json2/decoder2/tests/checker_test.v

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn test_check_if_json_match() {
2020
if err is json.JsonDecodeError {
2121
assert err.line == 1
2222
assert err.character == 1
23-
assert err.message == 'Data: Expected object, but got string_'
23+
assert err.message == 'Data: Expected object, but got string'
2424
}
2525
has_error = true
2626
}
@@ -115,20 +115,60 @@ fn test_check_json_format() {
115115
},
116116
{
117117
'json': '{"key": 123'
118-
'error': 'Syntax: EOF error: braces are not closed'
118+
'error': 'Syntax: Expecting object key' // improve message
119119
},
120120
{
121121
'json': '{"key": 123,'
122-
'error': 'Syntax: EOF error: Expecting object key after `,`'
122+
'error': 'Syntax: EOF: expected object key'
123123
},
124124
{
125125
'json': '{"key": 123, "key2": 456,}'
126-
'error': 'Syntax: Expecting object key after `,`'
126+
'error': 'Syntax: Cannot use `,`, before `}`'
127127
},
128128
{
129129
'json': '[[1, 2, 3], [4, 5, 6],]'
130130
'error': 'Syntax: Cannot use `,`, before `]`'
131131
},
132+
{
133+
'json': ' '
134+
'error': 'Syntax: EOF: empty json'
135+
},
136+
{
137+
'json': '"'
138+
'error': 'Syntax: EOF: string not closed'
139+
},
140+
{
141+
'json': '"not closed'
142+
'error': 'Syntax: EOF: string not closed'
143+
},
144+
{
145+
'json': '"\\"'
146+
'error': 'Syntax: EOF: string not closed'
147+
},
148+
{
149+
'json': '"\\u8"'
150+
'error': 'Syntax: short unicode escape sequence \\u8'
151+
},
152+
{
153+
'json': '['
154+
'error': 'Syntax: EOF: expected array end'
155+
},
156+
{
157+
'json': '[ '
158+
'error': 'Syntax: EOF: expected array end'
159+
},
160+
{
161+
'json': '{'
162+
'error': 'Syntax: EOF: expected object end'
163+
},
164+
{
165+
'json': '{ '
166+
'error': 'Syntax: EOF: expected object end'
167+
},
168+
{
169+
'json': '{"key": "value" '
170+
'error': 'Syntax: EOF: expected object end'
171+
},
132172
]
133173

134174
for json_and_error in json_and_error_message {

vlib/x/json2/decoder2/tests/decode_string_test.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fn test_json_string_invalid_escapes() {
3636
json.decode[string](r'"\x"') or {
3737
if err is json.JsonDecodeError {
3838
assert err.line == 1
39-
assert err.character == 2
39+
assert err.character == 3
4040
assert err.message == 'Syntax: unknown escape sequence'
4141
}
4242
has_error = true
@@ -48,7 +48,7 @@ fn test_json_string_invalid_escapes() {
4848
json.decode[string](r'"\u123"') or {
4949
if err is json.JsonDecodeError {
5050
assert err.line == 1
51-
assert err.character == 2
51+
assert err.character == 3
5252
assert err.message == 'Syntax: short unicode escape sequence \\u123'
5353
}
5454
has_error = true

vlib/x/json2/decoder2/tests/json2_tests/decoder_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn test_raw_decode_map_invalid() {
6060
if err is json.JsonDecodeError {
6161
assert err.line == 1
6262
assert err.character == 8
63-
assert err.message == 'Syntax: invalid value after object key'
63+
assert err.message == 'Syntax: expected `:`, got `,`'
6464
}
6565

6666
return

vlib/x/json2/decoder2/tests/json2_tests/json_module_compatibility_test/json_decode_todo_test.v

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn test_decode_error_message_should_have_enough_context_just_brace() {
5858
if err is json.JsonDecodeError {
5959
assert err.line == 1
6060
assert err.character == 1
61-
assert err.message == 'Syntax: EOF error: expecting a complete object after `{`'
61+
assert err.message == 'Syntax: EOF: expected object end'
6262
}
6363
return
6464
}
@@ -76,7 +76,7 @@ fn test_decode_error_message_should_have_enough_context_trailing_comma_at_end()
7676
if err is json.JsonDecodeError {
7777
assert err.line == 5
7878
assert err.character == 1
79-
assert err.message == 'Syntax: Expecting object key after `,`'
79+
assert err.message == 'Syntax: Cannot use `,`, before `}`'
8080
}
8181

8282
return
@@ -90,7 +90,7 @@ fn test_decode_error_message_should_have_enough_context_in_the_middle() {
9090
if err is json.JsonDecodeError {
9191
assert err.line == 1
9292
assert err.character == 40
93-
assert err.message == 'Syntax: invalid value. Unexpected character after string_ end'
93+
assert err.message == 'Syntax: invalid value. Unexpected character after string end'
9494
}
9595
return
9696
}

vlib/x/json2/tests/encode_struct_todo_test.vv

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import x.json2 as json
22
import time
33

44
const fixed_time = time.new(
5-
year: 2022
6-
month: 3
7-
day: 11
8-
hour: 13
5+
year: 2022
6+
month: 3
7+
day: 11
8+
hour: 13
99
minute: 54
1010
second: 25
1111
)

vlib/x/json2/types.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ enum ValueKind {
4444
unknown
4545
array
4646
object
47-
string_
47+
string
4848
number
4949
boolean
5050
null
@@ -56,7 +56,7 @@ fn (k ValueKind) str() string {
5656
.unknown { 'unknown' }
5757
.array { 'array' }
5858
.object { 'object' }
59-
.string_ { 'string' }
59+
.string { 'string' }
6060
.number { 'number' }
6161
.boolean { 'boolean' }
6262
.null { 'null' }

0 commit comments

Comments
 (0)