summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib.c62
-rw-r--r--txr.116
2 files changed, 78 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index c00e6401..03f28956 100644
--- a/lib.c
+++ b/lib.c
@@ -14820,6 +14820,16 @@ static int check_emit_circle(val obj, val out, struct strm_ctx *ctx, val self)
return 0;
}
+static void out_json_sym(val sym, val out, struct strm_ctx *ctx)
+{
+ put_char(chr('"'), out);
+ if (ctx)
+ obj_print_impl(sym, out, nil, ctx);
+ else
+ obj_print(sym, out, nil);
+ put_char(chr('"'), out);
+}
+
static void out_json_rec(val obj, val out, enum json_fmt jf,
struct strm_ctx *ctx)
{
@@ -15026,6 +15036,58 @@ static void out_json_rec(val obj, val out, enum json_fmt jf,
force_break(out);
return;
}
+ if (structp(obj)) {
+ val ty = typeof(obj);
+ val sl = slots(ty);
+ val iter;
+ val save_indent;
+ int force_br = 0;
+
+ if (jf == json_fmt_standard) {
+ put_string(lit("{\n"), out);
+ save_indent = inc_indent_abs(out, two);
+ put_string(lit("\"__type\" : "), out);
+ out_json_sym(ty, out, ctx);
+
+ for (iter = sl; iter; iter = cdr(iter)) {
+ val slsym = car(iter);
+
+ if (static_slot_p(ty, slsym))
+ continue;
+
+ put_string(lit(",\n"), out);
+ out_json_sym(slsym, out, ctx);
+ put_string(lit(" : "), out);
+ out_json_rec(slot(obj, slsym), out, jf, ctx);
+ }
+ put_string(lit("\n"), out);
+ } else {
+ put_char(chr('{'), out);
+ save_indent = inc_indent(out, zero);
+ put_string(lit("\"__type\":"), out);
+ out_json_sym(ty, out, ctx);
+
+ for (iter = sl; iter; iter = cdr(iter)) {
+ val slsym = car(iter);
+
+ if (static_slot_p(ty, slsym))
+ continue;
+
+ put_string(lit(","), out);
+ if (width_check(out, nil))
+ force_br = 1;
+ out_json_sym(slsym, out, ctx);
+ put_string(lit(":"), out);
+ out_json_rec(slot(obj, slsym), out, jf, ctx);
+ }
+ }
+
+ set_indent(out, save_indent);
+ put_char(chr('}'), out);
+ if (force_br)
+ force_break(out);
+ return;
+ }
break;
case FLNUM:
case NUM:
diff --git a/txr.1 b/txr.1
index 53d3377b..bda03dcc 100644
--- a/txr.1
+++ b/txr.1
@@ -84092,6 +84092,22 @@ A list of object is rendered in the same way as vector, in the JSON
.code []
notation. When such JSON notation is parsed, a vector is produced.
+A structure object is rendered into JSON using the
+.code {}
+object notation. The keys of the objects are the names of the
+symbols of the object type's non-static slots, appearing as a
+string. The values are the values of the slots. They must be JSON-conforming
+objects.
+The first entry of the object is a key named
+.str __type
+whose value is the structure type symbol, appearing as a string.
+Both the slot symbols and the type symbol may appear with a package
+qualifier, depending on the relationship of the symbols to the current
+package, according to similar rules as if the symbol were printed
+by the
+.code print
+function.
+
When integer objects are output, they may not constitute valid JSON, since the
JSON specification supports only IEEE 64 bit floating-point numbers. JSON
numbers are read as floating-point.