Merge pull request #3643 from korvahkh/fix-omitempty-comma

encoding/json: Fix struct marshal() emitting comma after omitted field
This commit is contained in:
gingerBill
2024-06-28 11:50:31 +01:00
committed by GitHub
+12 -10
View File
@@ -239,7 +239,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
case runtime.Type_Info_Array: case runtime.Type_Info_Array:
opt_write_start(w, opt, '[') or_return opt_write_start(w, opt, '[') or_return
for i in 0..<info.count { for i in 0..<info.count {
opt_write_iteration(w, opt, i) or_return opt_write_iteration(w, opt, i == 0) or_return
data := uintptr(v.data) + uintptr(i*info.elem_size) data := uintptr(v.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
} }
@@ -248,7 +248,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
case runtime.Type_Info_Enumerated_Array: case runtime.Type_Info_Enumerated_Array:
opt_write_start(w, opt, '[') or_return opt_write_start(w, opt, '[') or_return
for i in 0..<info.count { for i in 0..<info.count {
opt_write_iteration(w, opt, i) or_return opt_write_iteration(w, opt, i == 0) or_return
data := uintptr(v.data) + uintptr(i*info.elem_size) data := uintptr(v.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
} }
@@ -258,7 +258,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
opt_write_start(w, opt, '[') or_return opt_write_start(w, opt, '[') or_return
array := cast(^mem.Raw_Dynamic_Array)v.data array := cast(^mem.Raw_Dynamic_Array)v.data
for i in 0..<array.len { for i in 0..<array.len {
opt_write_iteration(w, opt, i) or_return opt_write_iteration(w, opt, i == 0) or_return
data := uintptr(array.data) + uintptr(i*info.elem_size) data := uintptr(array.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
} }
@@ -268,7 +268,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
opt_write_start(w, opt, '[') or_return opt_write_start(w, opt, '[') or_return
slice := cast(^mem.Raw_Slice)v.data slice := cast(^mem.Raw_Slice)v.data
for i in 0..<slice.len { for i in 0..<slice.len {
opt_write_iteration(w, opt, i) or_return opt_write_iteration(w, opt, i == 0) or_return
data := uintptr(slice.data) + uintptr(i*info.elem_size) data := uintptr(slice.data) + uintptr(i*info.elem_size)
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
} }
@@ -290,7 +290,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
for bucket_index in 0..<map_cap { for bucket_index in 0..<map_cap {
runtime.map_hash_is_valid(hs[bucket_index]) or_continue runtime.map_hash_is_valid(hs[bucket_index]) or_continue
opt_write_iteration(w, opt, i) or_return opt_write_iteration(w, opt, i == 0) or_return
i += 1 i += 1
key := rawptr(runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index)) key := rawptr(runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index))
@@ -356,7 +356,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
slice.sort_by(sorted[:], proc(i, j: Entry) -> bool { return i.key < j.key }) slice.sort_by(sorted[:], proc(i, j: Entry) -> bool { return i.key < j.key })
for s, i in sorted { for s, i in sorted {
opt_write_iteration(w, opt, i) or_return opt_write_iteration(w, opt, i == 0) or_return
opt_write_key(w, opt, s.key) or_return opt_write_key(w, opt, s.key) or_return
marshal_to_writer(w, s.value, opt) or_return marshal_to_writer(w, s.value, opt) or_return
} }
@@ -405,6 +405,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
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)
first_iteration := true
for name, i in info.names { for name, i in info.names {
omitempty := false omitempty := false
@@ -424,7 +425,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
continue continue
} }
opt_write_iteration(w, opt, i) or_return opt_write_iteration(w, opt, first_iteration) or_return
first_iteration = false
if json_name != "" { if json_name != "" {
opt_write_key(w, opt, json_name) or_return opt_write_key(w, opt, json_name) or_return
} else { } else {
@@ -588,10 +590,10 @@ opt_write_start :: proc(w: io.Writer, opt: ^Marshal_Options, c: byte) -> (err: i
} }
// insert comma separation and write indentations // insert comma separation and write indentations
opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) -> (err: io.Error) { opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, first_iteration: bool) -> (err: io.Error) {
switch opt.spec { switch opt.spec {
case .JSON, .JSON5: case .JSON, .JSON5:
if iteration > 0 { if !first_iteration {
io.write_byte(w, ',') or_return io.write_byte(w, ',') or_return
if opt.pretty { if opt.pretty {
@@ -602,7 +604,7 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int)
opt_write_indentation(w, opt) or_return opt_write_indentation(w, opt) or_return
case .MJSON: case .MJSON:
if iteration > 0 { if !first_iteration {
// on pretty no commas necessary // on pretty no commas necessary
if opt.pretty { if opt.pretty {
io.write_byte(w, '\n') or_return io.write_byte(w, '\n') or_return