pub const ATOM_SCALAR_BOUND: usize = 200;
#[must_use]
pub fn atom(text: &str) -> String {
let mut out = String::with_capacity(text.len().saturating_add(2));
out.push('"');
let mut omitted = false;
for (index, scalar) in text.chars().enumerate() {
if index >= ATOM_SCALAR_BOUND {
omitted = true;
break;
}
match scalar {
'"' => out.push_str("\\\""),
'\\' => out.push_str("\\\\"),
' '..='~' => out.push(scalar),
_ => {
let mut units = [0_u16; 2];
for unit in scalar.encode_utf16(&mut units) {
out.push_str("\\u");
for shift in [12_u32, 8, 4, 0] {
let nibble = (u32::from(*unit) >> shift) & 0xf;
out.push(char::from_digit(nibble, 16).unwrap_or('0'));
}
}
}
}
}
if omitted {
out.push_str("...");
}
out.push('"');
out
}
#[must_use]
pub fn atom_bytes(bytes: &[u8]) -> String {
let mut out = String::with_capacity(bytes.len().saturating_add(2));
out.push('"');
let mut omitted = false;
for (index, byte) in bytes.iter().enumerate() {
if index >= ATOM_SCALAR_BOUND {
omitted = true;
break;
}
match byte {
b'"' => out.push_str("\\\""),
b'\\' => out.push_str("\\\\"),
b' '..=b'~' => out.push(char::from(*byte)),
_ => {
out.push_str("\\u00");
for shift in [4_u32, 0] {
let nibble = (u32::from(*byte) >> shift) & 0xf;
out.push(char::from_digit(nibble, 16).unwrap_or('0'));
}
}
}
}
if omitted {
out.push_str("...");
}
out.push('"');
out
}