turbopack_core/
debug_id.rs1use turbo_rcstr::RcStr;
2use turbo_tasks_fs::rope::Rope;
3use twox_hash::xxhash3_128;
4
5pub fn generate_debug_id(content: &Rope) -> RcStr {
11 let mut hasher = xxhash3_128::Hasher::new();
12 for bytes in content.read() {
13 hasher.write(bytes.as_ref());
14 }
15 let hash = hasher.finish_128();
16 uuid::Uuid::from_u128(hash)
17 .as_hyphenated()
18 .to_string()
19 .into()
20}
21
22#[cfg(test)]
23mod tests {
24 use super::*;
25
26 #[test]
27 fn test_generate_debug_id_deterministic() {
28 let content = Rope::from("console.log('Hello World');");
30
31 let id1 = generate_debug_id(&content);
33 let id2 = generate_debug_id(&content);
34
35 assert_eq!(id1, id2);
37
38 assert_eq!(id1.len(), 36);
40 assert!(id1.contains('-'));
41 }
42
43 #[test]
44 fn test_generate_debug_id_different_content() {
45 let content1 = Rope::from("console.log('Hello');");
47 let content2 = Rope::from("console.log('World');");
48
49 let id1 = generate_debug_id(&content1);
51 let id2 = generate_debug_id(&content2);
52
53 assert_ne!(id1, id2);
55 }
56
57 #[test]
58 fn test_debug_id_format() {
59 let content = Rope::from("test content");
60 let debug_id = generate_debug_id(&content);
61
62 let parts: Vec<&str> = debug_id.split('-').collect();
64 assert_eq!(parts.len(), 5);
65 assert_eq!(parts[0].len(), 8);
66 assert_eq!(parts[1].len(), 4);
67 assert_eq!(parts[2].len(), 4);
68 assert_eq!(parts[3].len(), 4);
69 assert_eq!(parts[4].len(), 12);
70
71 assert_eq!(debug_id, debug_id.to_lowercase());
73 }
74}