diff options
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)!; +}; | 
