commit a51f33512a0740b9e2a81bc75abb6aec7481d42d
parent 2f8897a58bd120190d279e56cc7b8e9db8c90c64
Author: Sebastian <sebastian@sebsite.pw>
Date: Wed, 18 May 2022 23:41:12 -0400
encoding::json: add dump and dumpstr
Tests aren't included; those are added in the "expand tests" commit.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
3 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/encoding/json/dump.ha b/encoding/json/dump.ha
@@ -0,0 +1,84 @@
+// License: MPL-2.0
+// (c) 2022 Sebastian <sebastian@sebsite.pw>
+use fmt;
+use io;
+use strings;
+use strio;
+
+// Dumps a [[value]] into an [[io::handle]] as a string without any additional
+// formatting.
+export fn dump(out: io::handle, val: value) (size | io::error) = {
+ let z = 0z;
+ match (val) {
+ case let v: (f64 | bool) =>
+ z += fmt::fprint(out, v)?;
+ case let s: str =>
+ z += fmt::fprint(out, `"`)?;
+ let it = strings::iter(s);
+ for (true) match (strings::next(&it)) {
+ case void =>
+ break;
+ case let r: rune =>
+ switch (r) {
+ case '\b' =>
+ z += fmt::fprint(out, `\b`)?;
+ case '\f' =>
+ z += fmt::fprint(out, `\f`)?;
+ case '\n' =>
+ z += fmt::fprint(out, `\n`)?;
+ case '\r' =>
+ z += fmt::fprint(out, `\r`)?;
+ case '\t' =>
+ z += fmt::fprint(out, `\t`)?;
+ case '\"' =>
+ z += fmt::fprint(out, `\"`)?;
+ case '\\' =>
+ z += fmt::fprint(out, `\\`)?;
+ case =>
+ if (iscntrl(r)) {
+ z += fmt::fprintf(out, `\u{:04x}`,
+ r: u32)?;
+ } else {
+ z += fmt::fprint(out, r)?;
+ };
+ };
+ };
+ z += fmt::fprint(out, `"`)?;
+ case _null =>
+ z += fmt::fprint(out, "null")?;
+ case let a: []value =>
+ z += fmt::fprint(out, "[")?;
+ for (let i = 0z; i < len(a); i += 1) {
+ z += dump(out, a[i])?;
+ if (i < len(a) - 1) {
+ z += fmt::fprint(out, ",")?;
+ };
+ };
+ z += fmt::fprint(out, "]")?;
+ case let o: object =>
+ z += fmt::fprint(out, "{")?;
+ let comma = false;
+ let it = iter(&o);
+ for (true) match (next(&it)) {
+ case void => break;
+ case let pair: (const str, const *value) =>
+ if (comma) {
+ z += fmt::fprint(out, ",")?;
+ };
+ comma = true;
+ z += dump(out, pair.0)?;
+ z += fmt::fprint(out, ":")?;
+ z += dump(out, *pair.1)?;
+ };
+ z += fmt::fprint(out, "}")?;
+ };
+ return z;
+};
+
+// Dumps a [[value]] into a string without any additional formatting. The caller
+// must free the return value.
+export fn dumpstr(val: value) str = {
+ let s = strio::dynamic();
+ dump(&s, val)!;
+ return strio::string(&s);
+};
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -522,19 +522,21 @@ encoding_json() {
types.ha \
lex.ha \
load.ha \
+ dump.ha \
value.ha
else
gen_srcs encoding::json \
types.ha \
lex.ha \
load.ha \
+ dump.ha \
value.ha \
+test/lexer.ha \
+test/load.ha \
+test/value.ha
fi
gen_ssa encoding::json ascii bufio io strio os encoding::utf8 strings \
- strconv hash::fnv types
+ strconv hash::fnv fmt types
}
encoding_pem() {
diff --git a/stdlib.mk b/stdlib.mk
@@ -1070,9 +1070,10 @@ stdlib_encoding_json_any_srcs = \
$(STDLIB)/encoding/json/types.ha \
$(STDLIB)/encoding/json/lex.ha \
$(STDLIB)/encoding/json/load.ha \
+ $(STDLIB)/encoding/json/dump.ha \
$(STDLIB)/encoding/json/value.ha
-$(HARECACHE)/encoding/json/encoding_json-any.ssa: $(stdlib_encoding_json_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_types_$(PLATFORM))
+$(HARECACHE)/encoding/json/encoding_json-any.ssa: $(stdlib_encoding_json_any_srcs) $(stdlib_rt) $(stdlib_ascii_$(PLATFORM)) $(stdlib_bufio_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_strio_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_encoding_utf8_$(PLATFORM)) $(stdlib_strings_$(PLATFORM)) $(stdlib_strconv_$(PLATFORM)) $(stdlib_hash_fnv_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_types_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/encoding/json
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::json \
@@ -3190,12 +3191,13 @@ testlib_encoding_json_any_srcs = \
$(STDLIB)/encoding/json/types.ha \
$(STDLIB)/encoding/json/lex.ha \
$(STDLIB)/encoding/json/load.ha \
+ $(STDLIB)/encoding/json/dump.ha \
$(STDLIB)/encoding/json/value.ha \
$(STDLIB)/encoding/json/+test/lexer.ha \
$(STDLIB)/encoding/json/+test/load.ha \
$(STDLIB)/encoding/json/+test/value.ha
-$(TESTCACHE)/encoding/json/encoding_json-any.ssa: $(testlib_encoding_json_any_srcs) $(testlib_rt) $(testlib_ascii_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_hash_fnv_$(PLATFORM)) $(testlib_types_$(PLATFORM))
+$(TESTCACHE)/encoding/json/encoding_json-any.ssa: $(testlib_encoding_json_any_srcs) $(testlib_rt) $(testlib_ascii_$(PLATFORM)) $(testlib_bufio_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strio_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_encoding_utf8_$(PLATFORM)) $(testlib_strings_$(PLATFORM)) $(testlib_strconv_$(PLATFORM)) $(testlib_hash_fnv_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_types_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/encoding/json
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::json \