use std::collections::HashSet;
use lazy_static::lazy_static;
lazy_static! {
static ref VALID_CHARS: HashSet<char> = {
let mut m = HashSet::new();
for c in ("0123456789_ABCDEFGHIJKLMNOPQRSTVWXYZabcdefghijklmnopqrstuv" as &str).chars() {
m.insert(c);
}
m
};
}
pub fn convert_to_uuencode(s: String) -> Vec<u8> {
let mut out: Vec<u8> = Vec::with_capacity(s.len()*3);
for c in s.chars() {
if VALID_CHARS.contains(&c){
out.push(c as u8);
} else {
let utf8 = c as u32; out.push(b'U');
out.extend_from_slice(format!("{utf8:X}").as_bytes()); out.push(b'_');
}
}
out
}
pub fn convert_from_uuencode(s: Vec<u8>) -> String {
let mut out: Vec<char> = Vec::with_capacity(s.len());
let mut i=0;
loop {
let c = s[i];
if c == b'U' {
let from = i;
i+=1;
while s[i]!=b'_' {
i+=1;
}
let hex_part = &s[from..i];
let hex_string = String::from_utf8_lossy(hex_part);
let z = u32::from_str_radix(&hex_string, 16).expect(format!("Failed to interpret {:?} as a hex number, decoding uuencode", &hex_part).as_str());
unsafe {
out.push(
char::from_u32_unchecked(z)
);
}
i+=1;
} else {
out.push(
c as char
);
i+=1;
}
if i==out.len() {
break;
}
}
out.into_iter().collect()
}