aboutsummaryrefslogtreecommitdiff
path: root/core/encoding
diff options
context:
space:
mode:
authordozn <andymrsimmons@gmail.com>2025-12-29 12:23:54 -0800
committerdozn <andymrsimmons@gmail.com>2025-12-29 12:23:54 -0800
commitba68d75c6ff163c8c09793c9f42bab8229b6f490 (patch)
tree9adab6ae49bad81e5e308710df359478b8e4c7e0 /core/encoding
parent811f4c13cdc903387cc2a5bc1a34ebfdc763c9c2 (diff)
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.
Diffstat (limited to 'core/encoding')
-rw-r--r--core/encoding/json/marshal.odin26
1 files changed, 26 insertions, 0 deletions
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 {