mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Add json:"name,omitempty"
This commit is contained in:
@@ -366,12 +366,63 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
opt_write_end(w, opt, '}') or_return
|
opt_write_end(w, opt, '}') or_return
|
||||||
|
|
||||||
case runtime.Type_Info_Struct:
|
case runtime.Type_Info_Struct:
|
||||||
|
is_omitempty :: proc(v: any) -> bool {
|
||||||
|
v := v
|
||||||
|
if v == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
ti := runtime.type_info_core(type_info_of(v.id))
|
||||||
|
#partial switch info in ti.variant {
|
||||||
|
case runtime.Type_Info_String:
|
||||||
|
switch x in v {
|
||||||
|
case string:
|
||||||
|
return x == ""
|
||||||
|
case cstring:
|
||||||
|
return x == nil || x == ""
|
||||||
|
}
|
||||||
|
case runtime.Type_Info_Any:
|
||||||
|
return v.(any) == nil
|
||||||
|
case runtime.Type_Info_Type_Id:
|
||||||
|
return v.(typeid) == nil
|
||||||
|
case runtime.Type_Info_Pointer,
|
||||||
|
runtime.Type_Info_Multi_Pointer,
|
||||||
|
runtime.Type_Info_Procedure:
|
||||||
|
return (^rawptr)(v.data)^ == nil
|
||||||
|
case runtime.Type_Info_Dynamic_Array:
|
||||||
|
return (^runtime.Raw_Dynamic_Array)(v.data).len == 0
|
||||||
|
case runtime.Type_Info_Slice:
|
||||||
|
return (^runtime.Raw_Slice)(v.data).len == 0
|
||||||
|
case runtime.Type_Info_Union,
|
||||||
|
runtime.Type_Info_Bit_Set,
|
||||||
|
runtime.Type_Info_Soa_Pointer:
|
||||||
|
return reflect.is_nil(v)
|
||||||
|
case runtime.Type_Info_Map:
|
||||||
|
return (^runtime.Raw_Map)(v.data).len == 0
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
marshal_struct_fields :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: Marshal_Error) {
|
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))
|
ti := runtime.type_info_base(type_info_of(v.id))
|
||||||
info := ti.variant.(runtime.Type_Info_Struct)
|
info := ti.variant.(runtime.Type_Info_Struct)
|
||||||
for name, i in info.names {
|
for name, i in info.names {
|
||||||
json_name := reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "json")
|
omitempty := false
|
||||||
json_name = json_name_from_tag_value(json_name)
|
|
||||||
|
json_name, extra := json_name_from_tag_value(reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "json"))
|
||||||
|
for flag in strings.split_iterator(&extra, ",") {
|
||||||
|
switch flag {
|
||||||
|
case "omitempty":
|
||||||
|
omitempty = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id := info.types[i].id
|
||||||
|
data := rawptr(uintptr(v.data) + info.offsets[i])
|
||||||
|
the_value := any{data, id}
|
||||||
|
|
||||||
|
if is_omitempty(the_value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
opt_write_iteration(w, opt, i) or_return
|
opt_write_iteration(w, opt, i) or_return
|
||||||
if json_name != "" {
|
if json_name != "" {
|
||||||
@@ -379,18 +430,15 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
} else {
|
} else {
|
||||||
// Marshal the fields of 'using _: T' fields directly into the parent struct
|
// Marshal the fields of 'using _: T' fields directly into the parent struct
|
||||||
if info.usings[i] && name == "_" {
|
if info.usings[i] && name == "_" {
|
||||||
id := info.types[i].id
|
marshal_struct_fields(w, the_value, opt) or_return
|
||||||
data := rawptr(uintptr(v.data) + info.offsets[i])
|
|
||||||
marshal_struct_fields(w, any{data, id}, opt) or_return
|
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
opt_write_key(w, opt, name) or_return
|
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, the_value, opt) or_return
|
||||||
marshal_to_writer(w, any{data, id}, opt) or_return
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,10 +344,11 @@ unmarshal_expect_token :: proc(p: ^Parser, kind: Token_Kind, loc := #caller_loca
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
json_name_from_tag_value :: proc(value: string) -> (json_name: string) {
|
json_name_from_tag_value :: proc(value: string) -> (json_name, extra: string) {
|
||||||
json_name = value
|
json_name = value
|
||||||
if comma_index := strings.index_byte(json_name, ','); comma_index >= 0 {
|
if comma_index := strings.index_byte(json_name, ','); comma_index >= 0 {
|
||||||
json_name = json_name[:comma_index]
|
json_name = json_name[:comma_index]
|
||||||
|
extra = json_name[comma_index:]
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -393,7 +394,8 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
|||||||
|
|
||||||
for field, field_idx in fields {
|
for field, field_idx in fields {
|
||||||
tag_value := string(reflect.struct_tag_get(field.tag, "json"))
|
tag_value := string(reflect.struct_tag_get(field.tag, "json"))
|
||||||
if key == json_name_from_tag_value(tag_value) {
|
json_name, _ := json_name_from_tag_value(tag_value)
|
||||||
|
if key == json_name {
|
||||||
use_field_idx = field_idx
|
use_field_idx = field_idx
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user