use std::fmt::LowerHex;
use std::path::PathBuf;
pub trait HashPath {
fn hashed_path(self, depth: usize) -> PathBuf;
}
impl<T> HashPath for T
where
T: AsRef<[u8]> + IntoIterator,
T::Item: LowerHex,
{
fn hashed_path(self, depth: usize) -> PathBuf {
let mut path = PathBuf::new();
let the_hash = hex::encode(&self);
for (index, value) in self.into_iter().enumerate() {
path.push(format!("{value:02x}"));
if index >= depth - 1 {
break;
}
}
path.push(the_hash);
path
}
}
#[cfg(test)]
mod test {
use super::HashPath;
use md5::Md5;
use sha1::Sha1;
use sha2::{Digest, Sha256, Sha384, Sha512};
const THE_STRING: &[u8] = b"hello world pretend this is a file!";
#[test]
fn test_sha512_path() {
let mut hasher = Sha512::new();
hasher.update(THE_STRING);
let result = hasher.finalize();
assert_eq!(
"0f/84/0f84de02c2c3942e2c1b22819a8381270b5476574d8df50fa4b307cc61ffe45193ab7e4f9cdd4fa5a6c4abf8948e3220a8925c58a089473a4790533f50c79d7d",
result.hashed_path(2).to_str().unwrap()
);
assert_eq!(
"0f/84/de/0f84de02c2c3942e2c1b22819a8381270b5476574d8df50fa4b307cc61ffe45193ab7e4f9cdd4fa5a6c4abf8948e3220a8925c58a089473a4790533f50c79d7d",
result.hashed_path(3).to_str().unwrap()
);
}
#[test]
fn test_sha384_path() {
let mut hasher = Sha384::new();
hasher.update(THE_STRING);
let result = hasher.finalize();
assert_eq!(
"e4/05/e405fb66b64771f44efe0f16f7d98a2787cdd34f2ec481b3fefa5a458b2526b258a862ff55bb0c62bbfcee425629bc1e",
result.hashed_path(2).to_str().unwrap()
);
assert_eq!(
"e4/05/fb/e405fb66b64771f44efe0f16f7d98a2787cdd34f2ec481b3fefa5a458b2526b258a862ff55bb0c62bbfcee425629bc1e",
result.hashed_path(3).to_str().unwrap()
);
}
#[test]
fn test_sha256_path() {
let mut hasher = Sha256::new();
hasher.update(THE_STRING);
let result = hasher.finalize();
assert_eq!(
"12/77/1277be37873848472bcd3b58f76e70d4b01bf792b3e1bb8022f410d40804ab7e",
result.hashed_path(2).to_str().unwrap()
);
assert_eq!(
"12/77/be/1277be37873848472bcd3b58f76e70d4b01bf792b3e1bb8022f410d40804ab7e",
result.hashed_path(3).to_str().unwrap()
);
}
#[test]
fn test_sha1_path() {
let mut hasher = Sha1::new();
hasher.update(THE_STRING);
let result = hasher.finalize();
assert_eq!(
"d1/ed/d1ed345c982dd7bd8a260457fa2c0e59ed22f804",
result.hashed_path(2).to_str().unwrap()
);
assert_eq!(
"d1/ed/34/d1ed345c982dd7bd8a260457fa2c0e59ed22f804",
result.hashed_path(3).to_str().unwrap()
);
}
#[test]
fn test_md5_path() {
let mut hasher = Md5::new();
hasher.update(THE_STRING);
let result = hasher.finalize();
assert_eq!(
"a7/a9/a7a938a65a579cb64f632a90eff9862b",
result.hashed_path(2).to_str().unwrap()
);
assert_eq!(
"a7/a9/38/a7a938a65a579cb64f632a90eff9862b",
result.hashed_path(3).to_str().unwrap()
);
}
}