1use sha2::{Digest, Sha256};
4
5pub const CACHE_VERSION: &str = "1.0.0";
7
8pub fn hash_key(parts: &[&str]) -> String {
12 let mut hasher = Sha256::new();
13 hasher.update(CACHE_VERSION.as_bytes());
14 for part in parts {
15 hasher.update(b"|");
16 hasher.update(part.as_bytes());
17 }
18 format!("{:x}", hasher.finalize())
19}
20
21#[cfg(test)]
22mod tests {
23 use super::*;
24
25 #[test]
26 fn test_deterministic() {
27 let k1 = hash_key(&["a", "b", "c"]);
28 let k2 = hash_key(&["a", "b", "c"]);
29 assert_eq!(k1, k2);
30 }
31
32 #[test]
33 fn test_different_parts_differ() {
34 let k1 = hash_key(&["a", "b"]);
35 let k2 = hash_key(&["a", "c"]);
36 assert_ne!(k1, k2);
37 }
38
39 #[test]
40 fn test_different_length_parts_differ() {
41 let k1 = hash_key(&["a"]);
42 let k2 = hash_key(&["a", "b"]);
43 assert_ne!(k1, k2);
44 }
45
46 #[test]
47 fn test_empty_parts() {
48 let k = hash_key(&[]);
49 assert_eq!(k.len(), 64);
50 }
51
52 #[test]
53 fn test_key_is_64_hex_chars() {
54 let k = hash_key(&["test", "data"]);
55 assert_eq!(k.len(), 64);
56 assert!(k.chars().all(|c| c.is_ascii_hexdigit()));
57 }
58
59 #[test]
60 fn test_version_is_embedded() {
61 let k1 = hash_key(&["x"]);
65 let k2 = hash_key(&["x"]);
66 assert_eq!(k1, k2);
67 }
68}