mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
parent
37ed9dc95a
commit
aaeae8c964
3 changed files with 98 additions and 68 deletions
|
@ -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{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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],
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue