use std::path::{Path, PathBuf};
use uuid::Uuid;
pub fn uuid_to_path(
root: &Path,
uuid: Uuid,
extension: &str,
) -> PathBuf {
let mut buffer = [0; 32];
let encoded = uuid.to_simple().encode_lower(&mut buffer).to_string();
root.join(&encoded[0..1]).join(&encoded[1..2]).join(format!(
"{}.{}",
&encoded[0..32],
extension
))
}
pub fn uuid_and_hash_to_path(
root: &Path,
uuid: Uuid,
hash: u64,
extension: &str,
) -> PathBuf {
let mut buffer = [0; 32];
let uuid_encoded = uuid.to_simple().encode_lower(&mut buffer).to_string();
root.join(&uuid_encoded[0..1])
.join(&uuid_encoded[1..2])
.join(format!("{}-{:x}.{}", &uuid_encoded[0..32], hash, extension))
}
pub fn path_to_uuid(
root: &Path,
file_path: &Path,
) -> Option<Uuid> {
let relative_path_from_root = file_path.strip_prefix(root).ok()?;
let components: Vec<_> = relative_path_from_root.components().collect();
let mut filename = components[2].as_os_str().to_str().unwrap();
if components.len() != 3 {
return None;
}
if components[0].as_os_str().to_str().unwrap().as_bytes()[0] != filename.as_bytes()[0] {
return None;
}
if components[1].as_os_str().to_str().unwrap().as_bytes()[0] != filename.as_bytes()[1] {
return None;
}
if let Some(extension_begin) = filename.find('.') {
filename = filename.strip_suffix(&filename[extension_begin..]).unwrap();
}
u128::from_str_radix(&filename, 16)
.ok()
.map(|x| Uuid::from_u128(x))
}
pub fn path_to_uuid_and_hash(
root: &Path,
file_path: &Path,
) -> Option<(Uuid, u64)> {
let relative_path_from_root = file_path.strip_prefix(root).ok()?;
let components: Vec<_> = relative_path_from_root.components().collect();
let mut filename = components[2].as_os_str().to_str().unwrap();
if components.len() != 3 {
return None;
}
if components[0].as_os_str().to_str().unwrap().as_bytes()[0] != filename.as_bytes()[0] {
return None;
}
if components[1].as_os_str().to_str().unwrap().as_bytes()[0] != filename.as_bytes()[1] {
return None;
}
if let Some(extension_begin) = filename.find('.') {
filename = filename.strip_suffix(&filename[extension_begin..]).unwrap();
}
if let Some(hash_begin) = filename.find('-') {
let hash = u64::from_str_radix(&filename[(hash_begin + 1)..], 16).ok()?;
let uuid = u128::from_str_radix(&filename[0..hash_begin], 16)
.ok()
.map(|x| Uuid::from_u128(x))?;
Some((uuid, hash))
} else {
None
}
}