x.json2.decoder2: cleanup after #22751 (#22771)

This commit is contained in:
Hitalo Souza 2024-11-06 14:30:56 -04:00 committed by GitHub
parent 37ed9dc95a
commit aaeae8c964
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 98 additions and 68 deletions

View file

@ -618,66 +618,15 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
val = time.parse_rfc3339(string_time) or { time.Time{} } val = time.parse_rfc3339(string_time) or { time.Time{} }
} }
} $else $if T.unaliased_typ is $map { } $else $if T.unaliased_typ is $map {
map_info := decoder.current_node.value decoder.decode_map(mut val)!
return
if map_info.value_kind == .object {
map_position := map_info.position
map_end := map_position + map_info.length
decoder.current_node = decoder.current_node.next
for {
if decoder.current_node == unsafe { nil } {
break
}
key_info := decoder.current_node.value
if key_info.position >= map_end {
break
}
key := decoder.json[key_info.position + 1..key_info.position + key_info.length - 1]
decoder.current_node = decoder.current_node.next
value_info := decoder.current_node.value
if value_info.position + value_info.length >= map_end {
break
}
mut map_value := create_map_value(val)
decoder.decode_value(mut map_value)!
val[key] = map_value
}
}
} $else $if T.unaliased_typ is $array { } $else $if T.unaliased_typ is $array {
array_info := decoder.current_node.value decoder.decode_array(mut val)!
// return to avoid the next increment of the current node
if array_info.value_kind == .array { // this is because the current node is already incremented in the decode_array function
array_position := array_info.position // remove this line will cause the current node to be incremented twice
array_end := array_position + array_info.length // and bug recursive array decoding like `[][]int{}`
return
decoder.current_node = decoder.current_node.next
for {
if decoder.current_node == unsafe { nil } {
break
}
value_info := decoder.current_node.value
if value_info.position + value_info.length >= array_end {
break
}
mut array_element := create_array_element(val)
decoder.decode_value(mut array_element)!
val << array_element
}
}
} $else $if T.unaliased_typ is $struct { } $else $if T.unaliased_typ is $struct {
struct_info := decoder.current_node.value struct_info := decoder.current_node.value
@ -743,6 +692,69 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
} }
} }
fn (mut decoder Decoder) decode_array[T](mut val []T) ! {
array_info := decoder.current_node.value
if array_info.value_kind == .array {
decoder.current_node = decoder.current_node.next
array_position := array_info.position
array_end := array_position + array_info.length
for {
if decoder.current_node == unsafe { nil }
|| decoder.current_node.value.position >= array_end {
break
}
mut array_element := T{}
decoder.decode_value(mut array_element)!
val << array_element
}
}
}
fn (mut decoder Decoder) decode_map[K, V](mut val map[K]V) ! {
map_info := decoder.current_node.value
if map_info.value_kind == .object {
map_position := map_info.position
map_end := map_position + map_info.length
decoder.current_node = decoder.current_node.next
for {
if decoder.current_node == unsafe { nil }
|| decoder.current_node.value.position >= map_end {
break
}
key_info := decoder.current_node.value
if key_info.position >= map_end {
break
}
key := decoder.json[key_info.position + 1..key_info.position + key_info.length - 1]
decoder.current_node = decoder.current_node.next
value_info := decoder.current_node.value
if value_info.position + value_info.length >= map_end {
break
}
mut map_value := V{}
decoder.decode_value(mut map_value)!
val[key] = map_value
}
}
}
// get_value_kind returns the kind of a JSON value. // get_value_kind returns the kind of a JSON value.
fn get_value_kind(value u8) ValueKind { fn get_value_kind(value u8) ValueKind {
if value == u8(`"`) { if value == u8(`"`) {
@ -761,14 +773,6 @@ fn get_value_kind(value u8) ValueKind {
return .unknown return .unknown
} }
fn create_array_element[T](array []T) T {
return T{}
}
fn create_map_value[K, V](map_ map[K]V) V {
return V{}
}
fn create_value_from_optional[T](val ?T) T { fn create_value_from_optional[T](val ?T) T {
return T{} return T{}
} }

View file

@ -2,4 +2,26 @@ import x.json2.decoder2 as json
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]
assert json.decode[[]string]('["a", "b", "c"]')! == ['a', 'b', 'c']
assert json.decode[[]bool]('[true, false, true]')! == [true, false, true]
assert json.decode[[]f64]('[1.1, 2.2, 3.3]')! == [1.1, 2.2, 3.3]
// nested arrays
assert json.decode[[][]int]('[[1, 22], [333, 4444]]')! == [
[1, 22],
[333, 4444],
]
assert json.decode[[][]string]('[["a", "b"], ["c", "d"]]')! == [
['a', 'b'],
['c', 'd'],
]
assert json.decode[[][]bool]('[[true, false], [false, true]]')! == [
[true, false],
[false, true],
]
} }

View file

@ -42,7 +42,11 @@ fn test_array_of_strings() {
// assert json.decode[map[string]int]('{"val": 2}')! == {"val": 2} // assert json.decode[map[string]int]('{"val": 2}')! == {"val": 2}
// // nested map // // nested map
// assert json.decode[map[string]map[string]string]('{"val": {"val2": "2"}}')! == {"val": {"val2": "2"}} // assert json.decode[map[string]map[string]string]('{"val": {"val2": "2"}}')! == {
// 'val': {
// 'val2': '2'
// }
// }
// nested struct // nested struct
assert json.decode[Stru]('{"val": 1, "val2": "lala", "val3": {"a": 2, "brazilian_steak": "leleu"}}')! == Stru{ assert json.decode[Stru]('{"val": 1, "val2": "lala", "val3": {"a": 2, "brazilian_steak": "leleu"}}')! == Stru{