// License: MPL-2.0 // (c) 2022 Sebastian 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)!; };