v icon indicating copy to clipboard operation
v copied to clipboard

`x.json2` can't decode `array of struct` but `json` did it.

Open changrui opened this issue 8 months ago • 7 comments

Describe the bug

import x.json2
// import json

const json2_str = '[{"indicator":{"id":"NY.GDP.PCAP.CD","value":"GDP per capita (current US$)"},"country":{"id":"US","value":"United States"},"countryiso3code":"USA","date":"2024","value":null,"unit":"","obs_status":"","decimal":1},{"indicator":{"id":"NY.GDP.PCAP.CD","value":"GDP per capita (current US$)"},"country":{"id":"US","value":"United States"},"countryiso3code":"USA","date":"2023","value":82769.4122114216,"unit":"","obs_status":"","decimal":1},{"indicator":{"id":"NY.GDP.PCAP.CD","value":"GDP per capita (current US$)"},"country":{"id":"US","value":"United States"},"countryiso3code":"USA","date":"2022","value":78035.1753604212,"unit":"","obs_status":"","decimal":1}]'

fn decode_gdp_pc() ? {
	data := json2.decode[[]Data](json2_str) or { println('>>> Err: ${err}.') return none} //err
	// data := json.decode([]Data,json2_str) or { println('>>> Err: ${err}.') return none } //OK
	for k, v in data {
		println('${k}: ${v}')
	}
}

struct Data {
	indicator struct {id string value string}
	country struct {id string value string}
	iso3code string @[json: 'countryiso3code']
	date string
	value ?f64
	unit string
	obs_status string
	decimal int
}

Reproduction Steps

Run code above. https://play.vlang.io/p/7d9a69e82a

Expected Behavior

print out 3 struct.

Current Behavior

Err: The type []Data can't be decoded..

Possible Solution

No response

Additional Information/Context

No response

V version

V full version: V 0.4.10 b98ca31e263a4319839543088accd45915290866.27e4b02

Environment details (OS name and version, etc.)

windows 11 home.

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

changrui avatar May 04 '25 12:05 changrui

Connected to Huly®: V_0.6-22781

huly-for-github[bot] avatar May 04 '25 12:05 huly-for-github[bot]

You can use json2.decode_array[Data](...) as a workaround.

felipensp avatar May 04 '25 17:05 felipensp

You can use json2.decode_array[Data](...) as a workaround.

Sorry, json2.decode_array[]() has been deprecated to json2.decode[..]() after 2025-3-18, but ...

changrui avatar May 05 '25 13:05 changrui

Use data := json2.decoder2.decode[[]Data](json2_str) or {println('Err: $err') return none }, got: Expect number but got null error.

changrui avatar May 06 '25 00:05 changrui

Use data := json2.decoder2.decode[[]Data](json2_str) or {println('Err: $err') return none }, got: Expect number but got null error.

It seems easy to solve. Thanks for reporting it

enghitalo avatar May 06 '25 01:05 enghitalo

@changrui For now, as a workaround you can try to use value ?f64 @[omitempty]

import x.json2
import x.json2.decoder2
import json

const json2_str = '[{"indicator":{"id":"NY.GDP.PCAP.CD","value":"GDP per capita (current US$)"},"country":{"id":"US","value":"United States"},"countryiso3code":"USA","date":"2024","value":null,"unit":"","obs_status":"","decimal":1},{"indicator":{"id":"NY.GDP.PCAP.CD","value":"GDP per capita (current US$)"},"country":{"id":"US","value":"United States"},"countryiso3code":"USA","date":"2023","value":82769.4122114216,"unit":"","obs_status":"","decimal":1},{"indicator":{"id":"NY.GDP.PCAP.CD","value":"GDP per capita (current US$)"},"country":{"id":"US","value":"United States"},"countryiso3code":"USA","date":"2022","value":78035.1753604212,"unit":"","obs_status":"","decimal":1}]'

fn main(){
	decode_gdp_pc() or { println(err)}
}

fn decode_gdp_pc() ?[]Data {
// 	data := json2.decode[[]Data](json2_str) or { println('>>> Err: ${err}.') return none} 
	data := decoder2.decode[[]Data](json2_str) or { println('>>> Err: ${err}.') return none }
	for k, v in data {
		println('${k}: ${v}')
	}
	return data
}

struct Data {
	indicator struct {id string value string}
	country struct {id string value string}
	iso3code string @[json: 'countryiso3code']
	date string
	value ?f64 @[omitempty]
	unit string
	obs_status string
	decimal int
}
fn (w &Data)str() string {
	return '${w.iso3code}/${w.country.id}:${w.country.value},${w.date},${w.value or {0.0}:11.3f}'
}
0: USA/US:United States,2024,      0.000
1: USA/US:United States,2023,  82769.412
2: USA/US:United States,2022,  78035.175

enghitalo avatar May 06 '25 01:05 enghitalo

@enghitalo Thank you.

changrui avatar May 06 '25 22:05 changrui