use std::ffi::{OsStr, OsString};
use std::fmt::Write;
use std::{collections::HashSet, hash::Hash};
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[must_use]
pub fn osstr_to_vec(path: &OsStr) -> Vec<u8> {
path.as_encoded_bytes().to_vec()
}
#[must_use]
pub fn vec_to_osstr(vec: &[u8]) -> OsString {
unsafe { OsString::from_encoded_bytes_unchecked(vec.to_owned()) }
}
#[must_use]
pub fn vec_to_hex_string(vec: &[u8]) -> String {
vec.iter().fold(String::new(), |mut output, byte| {
let _ = write!(output, "{byte:02x}");
output
})
}
#[must_use]
pub fn hex_string_to_vec(hex_string: &str) -> Vec<u8> {
hex_string
.as_bytes()
.chunks(2)
.map(|chunk| u8::from_str_radix(&String::from_utf8(chunk.to_vec()).unwrap(), 16).unwrap())
.collect()
}
#[must_use]
pub fn mangle_str_filename(path_um: &str) -> String {
mangle_filename(path_um.as_bytes())
}
#[must_use]
pub fn mangle_filename(path_um: &[u8]) -> String {
let mut path = String::new();
if path_um.is_empty() {
return path;
}
path.push('f');
for &c in path_um {
if c.is_ascii() && c != b'%' && c != b'/' && c != b'\n' && c != b'\r' {
path.push(c as char);
} else {
path.push('%');
path.push_str(&format!("{:02x}", { c }));
}
}
path
}
#[must_use]
pub fn unmangle_filename(path_m: &str) -> Vec<u8> {
let mut path = Vec::<u8>::new();
if path_m.is_empty() {
return path;
}
let mut chars = path_m.chars();
if chars.next().unwrap() != 'f' {
return path;
}
while let Some(c) = chars.next() {
if c == '%' {
let hex = chars.next().unwrap().to_string() + &chars.next().unwrap().to_string();
let byte = u8::from_str_radix(&hex, 16).unwrap();
path.push(byte);
} else {
path.push(c as u8);
}
}
path
}
#[must_use]
pub fn mangle(path_um: &[u8]) -> String {
if path_um.is_empty() {
return String::new();
}
let mangled_components: Vec<String> =
path_um.split(|&c| c == b'/').map(mangle_filename).collect();
mangled_components.join("/")
}
#[must_use]
pub fn unique<T: Eq + Hash + Clone>(iterable: impl IntoIterator<Item = T>) -> Vec<T> {
let unique_elts: HashSet<T> = HashSet::from_iter(iterable);
unique_elts.into_iter().collect()
}