diff options
author | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:11:21 +0200 |
---|---|---|
committer | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:51:35 +0200 |
commit | ae44478b30d890fe0fb04022f44d474dcdcc3f9d (patch) | |
tree | 5f462459ae4b47d22114eed717d1382d08cf4dfe /encoding/json/dump.ha |
Diffstat (limited to 'encoding/json/dump.ha')
-rw-r--r-- | encoding/json/dump.ha | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/encoding/json/dump.ha b/encoding/json/dump.ha new file mode 100644 index 0000000..7e7dd8d --- /dev/null +++ b/encoding/json/dump.ha @@ -0,0 +1,81 @@ +// License: MPL-2.0 +// (c) 2022 Sebastian <sebastian@sebsite.pw> +use fmt; +use io; +use strings; +use memio; + +// 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 (const r => strings::next(&it)) { + 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{:.4x}`, + 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 = memio::dynamic(); + dump(&s, val)!; + return memio::string(&s)!; +}; |