Merge pull request #3068 from laytan/json-unmarshal-union

encoding/json: try to unmarshal into union variants
This commit is contained in:
Jeroen van Rijn
2024-01-03 19:13:36 +01:00
committed by GitHub
+18 -1
View File
@@ -204,8 +204,9 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
v := v v := v
ti := reflect.type_info_base(type_info_of(v.id)) ti := reflect.type_info_base(type_info_of(v.id))
if u, ok := ti.variant.(reflect.Type_Info_Union); ok && token.kind != .Null {
// NOTE: If it's a union with only one variant, then treat it as that variant // NOTE: If it's a union with only one variant, then treat it as that variant
if u, ok := ti.variant.(reflect.Type_Info_Union); ok && len(u.variants) == 1 && token.kind != .Null { if len(u.variants) == 1 {
variant := u.variants[0] variant := u.variants[0]
v.id = variant.id v.id = variant.id
ti = reflect.type_info_base(variant) ti = reflect.type_info_base(variant)
@@ -213,6 +214,22 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
tag := any{rawptr(uintptr(v.data) + u.tag_offset), u.tag_type.id} tag := any{rawptr(uintptr(v.data) + u.tag_offset), u.tag_type.id}
assign_int(tag, 1) assign_int(tag, 1)
} }
} else if v.id != Value {
for variant, i in u.variants {
variant_any := any{v.data, variant.id}
variant_p := p^
if err = unmarshal_value(&variant_p, variant_any); err == nil {
p^ = variant_p
raw_tag := i
if !u.no_nil { raw_tag += 1 }
tag := any{rawptr(uintptr(v.data) + u.tag_offset), u.tag_type.id}
assign_int(tag, raw_tag)
return
}
}
return UNSUPPORTED_TYPE
}
} }
switch &dst in v { switch &dst in v {