Skip to content

Commit

Permalink
json2.decoder2: prepare decoder in json2 to be replaced by json2.deco…
Browse files Browse the repository at this point in the history
…de2 (vlang#23078)
  • Loading branch information
enghitalo authored Dec 6, 2024
1 parent 210239f commit de3b184
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 22 deletions.
4 changes: 2 additions & 2 deletions cmd/tools/vls.v
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn (upd VlsUpdater) check_or_create_vls_folder() ! {

fn (upd VlsUpdater) manifest_config() !map[string]json2.Any {
manifest_buf := os.read_file(vls_manifest_path) or { '{}' }
manifest_contents := json2.raw_decode(manifest_buf)!.as_map()
manifest_contents := json2.decode[json2.Any](manifest_buf)!.as_map()
return manifest_contents
}

Expand Down Expand Up @@ -168,7 +168,7 @@ fn (upd VlsUpdater) download_prebuilt() ! {

upd.log('Finding prebuilt executables from GitHub release..')
resp := http.get('https://api.github.com/repos/vlang/vls/releases')!
releases_json := json2.raw_decode(resp.body)!.arr()
releases_json := json2.decode[json2.Any](resp.body)!.arr()
if releases_json.len == 0 {
return error('Unable to fetch latest VLS release data: No releases found.')
}
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/slow_tests/valgrind/import_x_json2.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import x.json2

fn main() {
x := '[[],[],[]]'
println(json2.raw_decode(x)!)
println(json2.decode[json2.Any](x)!)
}
6 changes: 3 additions & 3 deletions vlib/x/json2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn main() {
resp := http.get('https://reqres.in/api/products/1')!
// This returns an Any type
raw_product := json2.raw_decode(resp.body)!
raw_product := json2.decode[json2.Any](resp.body)!
}
```

Expand All @@ -90,7 +90,7 @@ import net.http
fn main() {
resp := http.get('https://reqres.in/api/products/1')!
raw_product := json2.raw_decode(resp.body)!
raw_product := json2.decode[json2.Any](resp.body)!
product := raw_product.as_map()
data := product['data'] as map[string]json2.Any
Expand Down Expand Up @@ -174,4 +174,4 @@ json2.encode_value(<some value to be encoded here>, mut buffer)!
sb.write(buffer)!
unsafe { buffer.free() }
```
```
10 changes: 4 additions & 6 deletions vlib/x/json2/decoder.v
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,13 @@ fn new_parser(srce string, convert_type bool) Parser {

// decode is a generic function that decodes a JSON string into the target type.
pub fn decode[T](src string) !T {
$if T is Any {
return raw_decode(src)!
}
res := raw_decode(src)!.as_map()
return decode_struct[T](T{}, res)
}

// decode_array is a generic function that decodes a JSON string into the array target type.
pub fn decode_array[T](src string) ![]T {
res := raw_decode(src)!.as_map()
return decode_struct_array(T{}, res)
}

// decode_struct_array is a generic function that decodes a JSON map into array struct T.
fn decode_struct_array[T](_ T, res map[string]Any) ![]T {
$if T is $struct {
Expand Down Expand Up @@ -428,6 +425,7 @@ fn (mut p Parser) decode_array() !Any {
return Any(items)
}

@[deprecated_after: '2025-03-18']
fn (mut p Parser) decode_object() !Any {
mut fields := map[string]Any{}
p.next_with_err()!
Expand Down
19 changes: 17 additions & 2 deletions vlib/x/json2/decoder2/decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -777,10 +777,25 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
}

if current_field_info.value.is_raw {
$if field.typ is $enum {
$if field.unaliased_typ is $enum {
// workaround to avoid the error: enums can only be assigned `int` values
return error('`raw` attribute cannot be used with enum fields')
} $else $if field.typ is string || field.typ is ?string {
} $else $if field.typ is ?string {
position := decoder.current_node.value.position
end := position + decoder.current_node.value.length

val.$(field.name) = decoder.json[position..end]
decoder.current_node = decoder.current_node.next

for {
if decoder.current_node == unsafe { nil }
|| decoder.current_node.value.position + decoder.current_node.value.length >= end {
break
}

decoder.current_node = decoder.current_node.next
}
} $else $if field.typ is string {
position := decoder.current_node.value.position
end := position + decoder.current_node.value.length

Expand Down
12 changes: 9 additions & 3 deletions vlib/x/json2/decoder2/decode_sumtype.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ fn (mut decoder Decoder) get_decoded_sumtype_workaround[T](initialized_sumtype T
$if initialized_sumtype is $sumtype {
$for v in initialized_sumtype.variants {
if initialized_sumtype is v {
mut val := initialized_sumtype
decoder.decode_value(mut val)!
return T(val)
$if v is $array {
mut val := initialized_sumtype.clone()
decoder.decode_value(mut val)!
return T(val)
} $else {
mut val := initialized_sumtype
decoder.decode_value(mut val)!
return T(val)
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions vlib/x/json2/decoder2/decoder_deprecated.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module decoder2

// decode_array is a generic function that decodes a JSON string into the array target type.
@[deprecated: 'use `decode` instead']
@[deprecated_after: '2025-03-18']
pub fn decode_array[T](src string) !T {
return decode[T](src)
}
1 change: 0 additions & 1 deletion vlib/x/json2/decoder2/tests/json_sumtype_test.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import x.json2.decoder2 as json
import x.json2
import time

type Prices = Price | []Price

Expand Down
17 changes: 17 additions & 0 deletions vlib/x/json2/decoder_deprecated.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ pub struct DecodeError {
}

// code returns the error code of DecodeError
@[deprecated_after: '2025-03-18']
pub fn (err DecodeError) code() int {
return 3
}

// msg returns the message of the DecodeError
@[deprecated_after: '2025-03-18']
pub fn (err DecodeError) msg() string {
return format_message(err.message, err.line, err.column)
}
Expand All @@ -23,11 +25,13 @@ pub struct InvalidTokenError {
}

// code returns the error code of the InvalidTokenError
@[deprecated_after: '2025-03-18']
pub fn (err InvalidTokenError) code() int {
return 2
}

// msg returns the message of the InvalidTokenError
@[deprecated_after: '2025-03-18']
pub fn (err InvalidTokenError) msg() string {
footer_text := if err.expected != .none { ', expecting `${err.expected}`' } else { '' }
return format_message('invalid token `${err.token.kind}`${footer_text}', err.token.line,
Expand All @@ -41,11 +45,13 @@ pub struct UnknownTokenError {
}

// code returns the error code of the UnknownTokenError
@[deprecated_after: '2025-03-18']
pub fn (err UnknownTokenError) code() int {
return 1
}

// msg returns the error message of the UnknownTokenError
@[deprecated_after: '2025-03-18']
pub fn (err UnknownTokenError) msg() string {
return format_message("unknown token '${err.token.lit}' when decoding ${err.kind}.",
err.token.line, err.token.full_col())
Expand All @@ -68,12 +74,15 @@ pub fn raw_decode(src string) !Any {
}

// Same with `raw_decode`, but skips the type conversion for certain types when decoding a certain value.
@[deprecated: 'use `decode[json.Any]` instead']
@[deprecated_after: '2025-03-18']
pub fn fast_raw_decode(src string) !Any {
mut p := new_parser(src, false)
return p.decode()
}

// decode - decodes provided JSON
@[deprecated_after: '2025-03-18']
pub fn (mut p Parser) decode() !Any {
p.next()
p.next_with_err()!
Expand All @@ -85,3 +94,11 @@ pub fn (mut p Parser) decode() !Any {
}
return fi
}

// decode_array is a generic function that decodes a JSON string into the array target type.
@[deprecated: 'use `decode` instead']
@[deprecated_after: '2025-03-18']
pub fn decode_array[T](src string) ![]T {
res := raw_decode(src)!.as_map()
return decode_struct_array(T{}, res)
}
2 changes: 1 addition & 1 deletion vlib/x/json2/encoder.v
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ fn encode_array[T](val []T) string {
// encode_pretty ...
pub fn encode_pretty[T](typed_data T) string {
encoded := encode(typed_data)
raw_decoded := raw_decode(encoded) or { 0 }
raw_decoded := decode[Any](encoded) or { 0 }
return raw_decoded.prettify_json_str()
}

Expand Down
4 changes: 1 addition & 3 deletions vlib/x/json2/tests/decode_map_test.v
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
module main

import x.json2

const data = '
Expand Down Expand Up @@ -31,7 +29,7 @@ const data = '
}
'

struct Comment {
pub struct Comment {
id string
message string
}
Expand Down

0 comments on commit de3b184

Please sign in to comment.