x.json2.decoder2: fix decoding of structs with option fields (fix #24409) (#24922)

This commit is contained in:
Larsimusrex 2025-07-18 10:03:21 +02:00 committed by GitHub
parent 736d79f455
commit 747af8c360
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 16 deletions

View File

@ -546,18 +546,7 @@ pub fn decode[T](val string) !T {
// decode_value decodes a value from the JSON nodes. // decode_value decodes a value from the JSON nodes.
@[manualfree] @[manualfree]
fn (mut decoder Decoder) decode_value[T](mut val T) ! { fn (mut decoder Decoder) decode_value[T](mut val T) ! {
$if T is $option { $if T.unaliased_typ is string {
value_info := decoder.current_node.value
if value_info.value_kind == .null {
decoder.current_node = decoder.current_node.next
// val = none // Is this line needed?
return
}
mut unwrapped_val := create_value_from_optional(val.$(field.name))
decoder.decode_value(mut unwrapped_val)!
val.$(field.name) = unwrapped_val
} $else $if T.unaliased_typ is string {
string_info := decoder.current_node.value string_info := decoder.current_node.value
if string_info.value_kind == .string_ { if string_info.value_kind == .string_ {
@ -815,11 +804,18 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
} }
} else { } else {
$if field.typ is $option { $if field.typ is $option {
mut unwrapped_val := create_value_from_optional(val.$(field.name)) or { // it would be nicer to do this at the start of the function
return // but options cant be passed to generic functions
if decoder.current_node.value.length == 4
&& decoder.json[decoder.current_node.value.position..decoder.current_node.value.position + 4] == 'null' {
val.$(field.name) = none
} else {
mut unwrapped_val := create_value_from_optional(val.$(field.name)) or {
return
}
decoder.decode_value(mut unwrapped_val)!
val.$(field.name) = unwrapped_val
} }
decoder.decode_value(mut unwrapped_val)!
val.$(field.name) = unwrapped_val
} $else { } $else {
decoder.decode_value(mut val.$(field.name))! decoder.decode_value(mut val.$(field.name))!
} }

View File

@ -0,0 +1,23 @@
import x.json2.decoder2
import json
struct Data {
name ?string
value string
}
fn test_decode_option_field() {
assert decoder2.decode[Data]('{"name": "test", "value": "hi"}')! == Data{
name: 'test'
value: 'hi'
}
assert decoder2.decode[Data]('{"name": null, "value": "hi"}')! == Data{
name: none
value: 'hi'
}
assert decoder2.decode[Data]('{"value": "hi"}')! == Data{
name: none
value: 'hi'
}
assert decoder2.decode[Data]('{"name": null, "value": null}') or { return } == Data{}
}