mirror of
https://github.com/vlang/v.git
synced 2025-09-10 07:47:20 -04:00
x.json2.decoder2: clean up (#22373)
This commit is contained in:
parent
1b812f6bdf
commit
81b9fd8b14
@ -25,33 +25,31 @@ pub enum ValueKind {
|
|||||||
boolean
|
boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// check_json
|
// check_json checks if the JSON string is valid.
|
||||||
fn check_json(val string) ! {
|
fn check_json(val string) ! {
|
||||||
if val == '' {
|
if val == '' {
|
||||||
return error('empty string')
|
return error('empty string')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode
|
// decode decodes a JSON string into a specified type.
|
||||||
pub fn decode[T](val string) !T {
|
pub fn decode[T](val string) !T {
|
||||||
check_json(val)!
|
check_json(val)!
|
||||||
|
|
||||||
mut nodes := []Node{}
|
mut nodes := []Node{}
|
||||||
|
|
||||||
mut decoder := Decoder{
|
mut decoder := Decoder{
|
||||||
json: val
|
json: val
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO needs performance improvements
|
// TODO: needs performance improvements
|
||||||
decoder.fulfill_nodes(mut nodes)
|
decoder.fulfill_nodes(mut nodes)
|
||||||
|
|
||||||
mut result := T{}
|
mut result := T{}
|
||||||
|
|
||||||
decoder.decode_value(nodes, &result)
|
decoder.decode_value(nodes, &result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_value
|
// decode_value decodes a value from the JSON nodes.
|
||||||
fn (mut decoder Decoder) decode_value[T](nodes []Node, val &T) {
|
fn (mut decoder Decoder) decode_value[T](nodes []Node, val &T) {
|
||||||
$if val is $option {
|
$if val is $option {
|
||||||
} $else $if T is string {
|
} $else $if T is string {
|
||||||
@ -76,32 +74,23 @@ fn (mut decoder Decoder) decode_value[T](nodes []Node, val &T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get_value_kind returns the kind of a JSON value.
|
||||||
fn get_value_kind(value rune) ValueKind {
|
fn get_value_kind(value rune) ValueKind {
|
||||||
mut value_kind := ValueKind.unknown
|
return match value {
|
||||||
|
`"` { .string_ }
|
||||||
if value == `"` {
|
`t`, `f` { .boolean }
|
||||||
value_kind = .string_
|
`{` { .object }
|
||||||
} else if value == `t` || value == `f` {
|
`[` { .array }
|
||||||
value_kind = .boolean
|
`0`...`9` { .number }
|
||||||
} else if value == `{` {
|
else { .unknown }
|
||||||
value_kind = .object
|
|
||||||
} else if value == `[` {
|
|
||||||
value_kind = .array
|
|
||||||
} else if value >= `0` && value <= `9` {
|
|
||||||
value_kind = .number
|
|
||||||
}
|
}
|
||||||
return value_kind
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_optional_value_in_actual_node
|
// decode_optional_value_in_actual_node decodes an optional value in a node.
|
||||||
fn (mut decoder Decoder) decode_optional_value_in_actual_node[T](node Node, val ?T) T {
|
fn (mut decoder Decoder) decode_optional_value_in_actual_node[T](node Node, val ?T) T {
|
||||||
start := (node.key_pos + node.key_len) + 3
|
start := (node.key_pos + node.key_len) + 3
|
||||||
mut end := start
|
mut end := start
|
||||||
for {
|
for decoder.json[end] != `,` && decoder.json[end] != `}` {
|
||||||
if decoder.json[end] == `,` || decoder.json[end] == `}` {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
end++
|
end++
|
||||||
}
|
}
|
||||||
mut value_kind := get_value_kind(decoder.json[start])
|
mut value_kind := get_value_kind(decoder.json[start])
|
||||||
@ -127,7 +116,7 @@ fn (mut decoder Decoder) decode_optional_value_in_actual_node[T](node Node, val
|
|||||||
return T{}
|
return T{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_struct
|
// decode_struct decodes a struct from the JSON nodes.
|
||||||
fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
||||||
$for field in T.fields {
|
$for field in T.fields {
|
||||||
for i := 0; i < nodes.len; i++ {
|
for i := 0; i < nodes.len; i++ {
|
||||||
@ -140,15 +129,10 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
|||||||
} {
|
} {
|
||||||
start := (node.key_pos + node.key_len) + 3
|
start := (node.key_pos + node.key_len) + 3
|
||||||
mut end := start
|
mut end := start
|
||||||
for {
|
for decoder.json[end] != `,` && decoder.json[end] != `}` {
|
||||||
if decoder.json[end] == `,` || decoder.json[end] == `}` {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
end++
|
end++
|
||||||
}
|
}
|
||||||
|
value_kind := get_value_kind(decoder.json[start])
|
||||||
mut value_kind := get_value_kind(decoder.json[start])
|
|
||||||
$if field.indirections != 0 {
|
$if field.indirections != 0 {
|
||||||
// REVIEW Needs clone?
|
// REVIEW Needs clone?
|
||||||
$if field.indirections == 1 {
|
$if field.indirections == 1 {
|
||||||
@ -257,10 +241,10 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
|||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
} $else $if field.typ is string {
|
} $else $if field.typ is string {
|
||||||
if value_kind == .string_ {
|
value.$(field.name) = if value_kind == .string_ {
|
||||||
value.$(field.name) = decoder.json[start + 1..end - 1]
|
decoder.json[start + 1..end - 1]
|
||||||
} else {
|
} else {
|
||||||
value.$(field.name) = decoder.json[start..end]
|
decoder.json[start..end]
|
||||||
}
|
}
|
||||||
} $else $if field.typ in [$int, $float] {
|
} $else $if field.typ in [$int, $float] {
|
||||||
$if field.typ is i8 {
|
$if field.typ is i8 {
|
||||||
@ -287,11 +271,7 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
|||||||
value.$(field.name) = decoder.json[start..end].f64()
|
value.$(field.name) = decoder.json[start..end].f64()
|
||||||
}
|
}
|
||||||
} $else $if field.typ is bool {
|
} $else $if field.typ is bool {
|
||||||
if decoder.json[start] == `t` {
|
value.$(field.name) = decoder.json[start] == `t`
|
||||||
value.$(field.name) = true
|
|
||||||
} else if decoder.json[start] == `f` {
|
|
||||||
value.$(field.name) = false
|
|
||||||
}
|
|
||||||
} $else $if field.typ is time.Time {
|
} $else $if field.typ is time.Time {
|
||||||
if value_kind == .string_ {
|
if value_kind == .string_ {
|
||||||
value.$(field.name) = time.parse_rfc3339(decoder.json[start + 1..end - 1]) or {
|
value.$(field.name) = time.parse_rfc3339(decoder.json[start + 1..end - 1]) or {
|
||||||
@ -300,7 +280,7 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
|||||||
}
|
}
|
||||||
} $else $if field.typ is $struct {
|
} $else $if field.typ is $struct {
|
||||||
if node.children != none {
|
if node.children != none {
|
||||||
decoder.decode_value(node.children or { panic('It will never happens') },
|
decoder.decode_value(node.children or { panic('It will never happen') },
|
||||||
value.$(field.name))
|
value.$(field.name))
|
||||||
}
|
}
|
||||||
} $else $if field.typ is $array {
|
} $else $if field.typ is $array {
|
||||||
@ -308,12 +288,9 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
} $else $if field.typ is $map {
|
} $else $if field.typ is $map {
|
||||||
if value_kind == .object {
|
if value_kind == .object && node.children != none {
|
||||||
if node.children != none {
|
decoder.decode_map(node.children or { panic('It will never happen') }, mut
|
||||||
decoder.decode_map(node.children or {
|
value.$(field.name))
|
||||||
panic('It will never happens')
|
|
||||||
}, mut value.$(field.name))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} $else $if field.typ is $enum {
|
} $else $if field.typ is $enum {
|
||||||
value.$(field.name) = decoder.json[start..end].int()
|
value.$(field.name) = decoder.json[start..end].int()
|
||||||
@ -365,46 +342,42 @@ fn (mut decoder Decoder) decode_struct[T](nodes []Node, value &T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn (mut decoder Decoder) decode_map[K, V](nodes []Node, mut val map[K]V) {
|
// decode_map decodes a map from the JSON nodes.
|
||||||
fn (mut decoder Decoder) decode_map[T](nodes []Node, mut val T) {
|
fn (mut decoder Decoder) decode_map[T](nodes []Node, mut val T) {
|
||||||
for i := 0; i < nodes.len; i++ {
|
for i := 0; i < nodes.len; i++ {
|
||||||
mut node := nodes[i]
|
mut node := nodes[i]
|
||||||
|
|
||||||
start := (node.key_pos + node.key_len) + 3
|
start := (node.key_pos + node.key_len) + 3
|
||||||
mut end := start
|
mut end := start
|
||||||
|
for decoder.json[end] != `,` && decoder.json[end] != `}` {
|
||||||
for {
|
|
||||||
if decoder.json[end] == `,` || decoder.json[end] == `}` {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
end++
|
end++
|
||||||
}
|
}
|
||||||
|
value_kind := get_value_kind(decoder.json[start])
|
||||||
mut value_kind := get_value_kind(decoder.json[start])
|
val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = if value_kind == .string_ {
|
||||||
|
decoder.json[start + 1..end - 1]
|
||||||
if value_kind == .string_ {
|
|
||||||
val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = decoder.json[start + 1..end - 1]
|
|
||||||
} else {
|
} else {
|
||||||
val[decoder.json[node.key_pos..node.key_pos + node.key_len]] = decoder.json[start..end]
|
decoder.json[start..end]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fulfill_nodes
|
// fulfill_nodes fills the nodes from the JSON string.
|
||||||
fn (mut decoder Decoder) fulfill_nodes(mut nodes []Node) {
|
fn (mut decoder Decoder) fulfill_nodes(mut nodes []Node) {
|
||||||
mut inside_string := false
|
mut inside_string := false
|
||||||
mut inside_key := false
|
mut inside_key := false
|
||||||
|
|
||||||
mut actual_key_len := 0
|
mut actual_key_len := 0
|
||||||
|
|
||||||
for decoder.idx < decoder.json.len {
|
for decoder.idx < decoder.json.len {
|
||||||
letter := decoder.json[decoder.idx]
|
letter := decoder.json[decoder.idx]
|
||||||
if letter == ` ` && !inside_string {
|
match letter {
|
||||||
} else if letter == `\"` {
|
` ` {
|
||||||
|
if !inside_string {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`\"` {
|
||||||
if decoder.json[decoder.idx - 1] == `{` || decoder.json[decoder.idx - 2] == `,` {
|
if decoder.json[decoder.idx - 1] == `{` || decoder.json[decoder.idx - 2] == `,` {
|
||||||
inside_key = true
|
inside_key = true
|
||||||
} else if decoder.json[decoder.idx + 1] == `:` {
|
} else if decoder.json[decoder.idx + 1] == `:` {
|
||||||
@ -427,17 +400,17 @@ fn (mut decoder Decoder) fulfill_nodes(mut nodes []Node) {
|
|||||||
key_len: actual_key_len
|
key_len: actual_key_len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inside_key = false
|
inside_key = false
|
||||||
}
|
}
|
||||||
inside_string = !inside_string
|
inside_string = !inside_string
|
||||||
decoder.idx++
|
decoder.idx++
|
||||||
continue
|
continue
|
||||||
} else if letter == `:` {
|
}
|
||||||
|
`:` {
|
||||||
actual_key_len = 0
|
actual_key_len = 0
|
||||||
} else if letter == `,` || letter == `:` || letter == `{` || letter == `}` || letter == `[`
|
}
|
||||||
|| letter == `]` {
|
`,`, `{`, `}`, `[`, `]` {}
|
||||||
} else {
|
else {}
|
||||||
}
|
}
|
||||||
if inside_key {
|
if inside_key {
|
||||||
actual_key_len++
|
actual_key_len++
|
||||||
|
Loading…
x
Reference in New Issue
Block a user