encoding/json: try to unmarshal into union variants

This commit is contained in:
Laytan Laats
2024-01-03 19:02:30 +01:00
parent ee97c5958f
commit 8c10f4cdde
+25 -8
View File
@@ -204,14 +204,31 @@ 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))
// 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 && token.kind != .Null {
if u, ok := ti.variant.(reflect.Type_Info_Union); ok && len(u.variants) == 1 && token.kind != .Null { // NOTE: If it's a union with only one variant, then treat it as that variant
variant := u.variants[0] if len(u.variants) == 1 {
v.id = variant.id variant := u.variants[0]
ti = reflect.type_info_base(variant) v.id = variant.id
if !reflect.is_pointer_internally(variant) { ti = reflect.type_info_base(variant)
tag := any{rawptr(uintptr(v.data) + u.tag_offset), u.tag_type.id} if !reflect.is_pointer_internally(variant) {
assign_int(tag, 1) tag := any{rawptr(uintptr(v.data) + u.tag_offset), u.tag_type.id}
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
} }
} }