fn hex_decode(hex: &str) -> Option<String> {
let bytes = hex.as_bytes();
if !bytes.len().is_multiple_of(2) {
return None;
}
let mut out = Vec::with_capacity(bytes.len() / 2);
for chunk in bytes.chunks(2) {
let hi = hex_nibble(chunk[0])?;
let lo = hex_nibble(chunk[1])?;
out.push((hi << 4) | lo);
}
String::from_utf8(out).ok()
}
fn hex_nibble(b: u8) -> Option<u8> {
match b {
b'0'..=b'9' => Some(b - b'0'),
b'A'..=b'F' => Some(b - b'A' + 10),
b'a'..=b'f' => Some(b - b'a' + 10),
_ => None,
}
}
pub(crate) fn xtgettcap_lookup(hex_key: &str) -> Option<&'static [u8]> {
let name = hex_decode(hex_key)?;
match name.as_str() {
"RGB" => Some(b"8"),
"Tc" => Some(b""),
"Smulx" => Some(b"\\E[4:%p1%dm"),
"Ss" => Some(b"\\E[%p1%d q"),
"Se" => Some(b"\x1b[2 q"),
"hpa" => Some(b"\\E[%i%p1%dG"),
"sitm" => Some(b"\x1b[3m"),
"ritm" => Some(b"\x1b[23m"),
"Ms" => Some(b"\\E]52;%p1%s;%p2%s\\007"),
_ => None,
}
}
pub(crate) fn xtgettcap_is_tn(hex_key: &str) -> bool {
hex_decode(hex_key).as_deref() == Some("TN")
}