///|
let hex_digits : String = "0123456789abcdef"
///|
/// Write a JSON string literal with serde_json's escaping rules: only `"`,
/// `\` and control characters are escaped; everything else is emitted as-is.
pub fn write_escaped_str(buf : StringBuilder, s : StringView) -> Unit {
buf.write_char('"')
for c in s {
match c {
'"' => buf.write_string("\\\"")
'\\' => buf.write_string("\\\\")
'\b' => buf.write_string("\\b")
'\t' => buf.write_string("\\t")
'\n' => buf.write_string("\\n")
'\u{0C}' => buf.write_string("\\f")
'\r' => buf.write_string("\\r")
c if c.to_int() < 0x20 => {
let n = c.to_int()
buf.write_string("\\u00")
buf.write_char(hex_digits.get_char(n >> 4).unwrap())
buf.write_char(hex_digits.get_char(n & 0xF).unwrap())
}
c => buf.write_char(c)
}
}
buf.write_char('"')
}
///|
fn write_compact(buf : StringBuilder, v : Value) -> Unit {
match v {
Null => buf.write_string("null")
Bool(true) => buf.write_string("true")
Bool(false) => buf.write_string("false")
Number(n) => buf.write_string(n.to_string())
String(s) => write_escaped_str(buf, s)
Array(xs) => {
buf.write_char('[')
for i, x in xs {
if i > 0 {
buf.write_char(',')
}
write_compact(buf, x)
}
buf.write_char(']')
}
Object(o) => {
buf.write_char('{')
let mut first = true
for k, x in o {
if !first {
buf.write_char(',')
}
first = false
write_escaped_str(buf, k)
buf.write_char(':')
write_compact(buf, x)
}
buf.write_char('}')
}
}
}
///|
fn write_indent(buf : StringBuilder, level : Int) -> Unit {
for _ in 0.. Unit {
match v {
Array(xs) => {
if xs.is_empty() {
buf.write_string("[]")
return
}
buf.write_char('[')
for i, x in xs {
buf.write_string(if i > 0 { ",\n" } else { "\n" })
write_indent(buf, level + 1)
write_pretty(buf, x, level + 1)
}
buf.write_char('\n')
write_indent(buf, level)
buf.write_char(']')
}
Object(o) => {
if o.is_empty() {
buf.write_string("{}")
return
}
buf.write_char('{')
let mut first = true
for k, x in o {
buf.write_string(if first { "\n" } else { ",\n" })
first = false
write_indent(buf, level + 1)
write_escaped_str(buf, k)
buf.write_string(": ")
write_pretty(buf, x, level + 1)
}
buf.write_char('\n')
write_indent(buf, level)
buf.write_char('}')
}
_ => write_compact(buf, v)
}
}