From ba68d75c6ff163c8c09793c9f42bab8229b6f490 Mon Sep 17 00:00:00 2001 From: dozn Date: Mon, 29 Dec 2025 12:23:54 -0800 Subject: [PATCH 1/2] Add JSON5/SJSON Comments When Marshalling Allows user-facing JSON5/SJSON to have comments explaining field usage. `json.Marshal_Options.pretty` must be enabled since we only use single-line comments (not to mention it wouldn't be terribly useful without `pretty` set anyways). We don't escape anything, so `\n` will display as "\n", but you're still able to enter in a proper newline character and it'll be displayed on multiple lines. --- core/encoding/json/marshal.odin | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index e563c326a..bed2018e3 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -413,6 +413,12 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: } opt_write_iteration(w, opt, first_iteration) or_return + + if opt.pretty { + comment := reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "jsoncomment") + opt_write_comment(w, opt, &comment) or_return + } + first_iteration = false if json_name != "" { opt_write_key(w, opt, json_name) or_return @@ -533,6 +539,26 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: return } +// Newlines are split into multiple comment lines +opt_write_comment :: proc(w: io.Writer, opt: ^Marshal_Options, comment: ^string) -> (err: io.Error) { + if comment^ == "" { + return nil + } + + switch opt.spec { + case .JSON5, .MJSON: + for line in strings.split_iterator(comment, "\n") { + io.write_string(w, "// ") or_return + io.write_string(w, line) or_return + io.write_rune(w, '\n') or_return + opt_write_indentation(w, opt) or_return + } + case .JSON: return nil + } + + return nil +} + // write key as quoted string or with optional quotes in mjson opt_write_key :: proc(w: io.Writer, opt: ^Marshal_Options, name: string) -> (err: io.Error) { switch opt.spec { From affaefc13ace1ac95b97c043314da13d4587eb44 Mon Sep 17 00:00:00 2001 From: dozn Date: Tue, 30 Dec 2025 04:42:06 -0800 Subject: [PATCH 2/2] Moved `first_iteration` up a couple lines so it makes sense readability-wise. --- core/encoding/json/marshal.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index bed2018e3..acf12331a 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -413,13 +413,13 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: } opt_write_iteration(w, opt, first_iteration) or_return + first_iteration = false if opt.pretty { comment := reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "jsoncomment") opt_write_comment(w, opt, &comment) or_return } - first_iteration = false if json_name != "" { opt_write_key(w, opt, json_name) or_return } else {