aboutsummaryrefslogtreecommitdiff
path: root/core/encoding/json
diff options
context:
space:
mode:
authorFranz Höltermann <Francis_the_cat@gmx.de>2024-03-26 20:22:51 +0100
committerFranz Höltermann <Francis_the_cat@gmx.de>2024-03-26 20:22:51 +0100
commit92a5666c1cc6a5b76d984be4394b5daabdf6fc03 (patch)
treea1e8665ffaef26fc4ac7d37096aa12b6bf41ab68 /core/encoding/json
parent63d6b4752bcbc5ca28adbd13ef91fee25d4f7465 (diff)
Json: fields on structs like 'using _: T' will now have T's fields
marshalled directly into the parent type without an '"_":{ ... }'. This seems like desirable behavior to me, since you can't access the fields with 'Parent_Type._.field' either.
Diffstat (limited to 'core/encoding/json')
-rw-r--r--core/encoding/json/marshal.odin41
1 files changed, 27 insertions, 14 deletions
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin
index f7ce7a120..985de6880 100644
--- a/core/encoding/json/marshal.odin
+++ b/core/encoding/json/marshal.odin
@@ -367,23 +367,36 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
opt_write_end(w, opt, '}') or_return
case runtime.Type_Info_Struct:
- opt_write_start(w, opt, '{') or_return
-
- for name, i in info.names {
- json_name := reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "json")
+ marshal_struct_fields :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: Marshal_Error) {
+ ti := runtime.type_info_base(type_info_of(v.id))
+ info := ti.variant.(runtime.Type_Info_Struct)
+ for name, i in info.names {
+ json_name := reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "json")
+
+ opt_write_iteration(w, opt, i) or_return
+ if json_name != "" {
+ opt_write_key(w, opt, json_name) or_return
+ } else {
+ // Marshal the fields of 'using _: T' fields directly into the parent struct
+ if info.usings[i] && name == "_" {
+ id := info.types[i].id
+ data := rawptr(uintptr(v.data) + info.offsets[i])
+ marshal_struct_fields(w, any{data, id}, opt) or_return
+ continue
+ } else {
+ opt_write_key(w, opt, name) or_return
+ }
+ }
- opt_write_iteration(w, opt, i) or_return
- if json_name != "" {
- opt_write_key(w, opt, json_name) or_return
- } else {
- opt_write_key(w, opt, name) or_return
+ id := info.types[i].id
+ data := rawptr(uintptr(v.data) + info.offsets[i])
+ marshal_to_writer(w, any{data, id}, opt) or_return
}
-
- id := info.types[i].id
- data := rawptr(uintptr(v.data) + info.offsets[i])
- marshal_to_writer(w, any{data, id}, opt) or_return
+ return
}
-
+
+ opt_write_start(w, opt, '{') or_return
+ marshal_struct_fields(w, v, opt) or_return
opt_write_end(w, opt, '}') or_return
case runtime.Type_Info_Union: