pub(crate) const HEX_SHIFT: u32 = 4;
pub(crate) const HEX_MASK: u32 = 0x0F;
pub(crate) const HEX: [char; 16] = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
];
pub(crate) const U_HEX: [char; 16] = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
];
#[inline]
pub(crate) const fn char_mask(c: char) -> u32 {
1 << (c as u32 & 31)
}
#[inline]
pub(crate) const fn char_bucket(c: char) -> usize {
(c as u32 >> 5) as usize
}
#[inline]
pub(crate) fn encode_as_hex_byte(escape_char: char, output: &mut String, character: char) {
output.push(escape_char);
output.push('x');
output.push(HEX[(character as u32 >> HEX_SHIFT) as usize]);
output.push(HEX[(character as u32 & HEX_MASK) as usize]);
}
#[inline]
pub(crate) fn encode_as_unicode(escape_char: char, output: &mut String, character: char) {
output.push(escape_char);
output.push('u');
output.push(HEX[(character as u32 >> (3 * HEX_SHIFT)) as usize & HEX_MASK as usize]);
output.push(HEX[(character as u32 >> (2 * HEX_SHIFT)) as usize & HEX_MASK as usize]);
output.push(HEX[(character as u32 >> (1 * HEX_SHIFT)) as usize & HEX_MASK as usize]);
output.push(HEX[(character as u32 & HEX_MASK) as usize]);
}
pub(crate) fn dump_masks_to_ascii(masks: &[u32; 4]) {
println!("Dumping Mask Values (0-127)");
for char in '\u{0000}'..='\u{007F}' {
let bucket = char_bucket(char);
let mask = char_mask(char);
if (masks[bucket] & mask) != 0 {
println!("{char:?} {}: VALID", char as u32);
} else {
println!("{char:?} {}: INVALID", char as u32);
}
}
}