libdd_common/machine_id/
mod.rs1use std::sync::LazyLock;
18
19#[cfg(target_os = "linux")]
20mod linux;
21
22#[cfg(target_os = "macos")]
23mod macos;
24
25#[cfg(windows)]
26mod windows;
27
28pub(crate) fn normalize_uuid(raw: &str) -> String {
32 let hex: String = raw
33 .chars()
34 .filter(|c| c.is_ascii_hexdigit())
35 .flat_map(char::to_lowercase)
36 .collect();
37
38 if hex.len() != 32 {
39 return String::new();
40 }
41
42 format!(
43 "{}-{}-{}-{}-{}",
44 &hex[0..8],
45 &hex[8..12],
46 &hex[12..16],
47 &hex[16..20],
48 &hex[20..32],
49 )
50}
51
52static MACHINE_ID: LazyLock<String> = LazyLock::new(|| {
53 let raw = {
54 #[cfg(target_os = "linux")]
55 {
56 linux::get_machine_id_impl()
57 }
58 #[cfg(target_os = "macos")]
59 {
60 macos::get_machine_id_impl()
61 }
62 #[cfg(windows)]
63 {
64 windows::get_machine_id_impl()
65 }
66 #[cfg(not(any(target_os = "linux", target_os = "macos", windows)))]
67 {
68 String::new()
69 }
70 };
71 normalize_uuid(&raw)
72});
73
74pub fn get_machine_id() -> &'static str {
77 MACHINE_ID.as_str()
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn cached_value_is_stable() {
86 assert_eq!(get_machine_id(), get_machine_id());
87 }
88
89 #[test]
90 fn value_has_uuid_shape_if_nonempty() {
91 let id = get_machine_id();
92 if id.is_empty() {
93 return;
94 }
95 assert_eq!(id.len(), 36);
96 for (i, c) in id.chars().enumerate() {
97 if [8, 13, 18, 23].contains(&i) {
98 assert_eq!(c, '-');
99 } else {
100 assert!(c.is_ascii_hexdigit() && !c.is_ascii_uppercase());
101 }
102 }
103 }
104
105 #[test]
106 fn normalize_bare_hex_inserts_hyphens() {
107 assert_eq!(
108 normalize_uuid("b08fa8a2b01a4d2bbd95fec7e30c5aec"),
109 "b08fa8a2-b01a-4d2b-bd95-fec7e30c5aec"
110 );
111 }
112
113 #[test]
114 fn normalize_uppercase_uuid_lowercased() {
115 assert_eq!(
116 normalize_uuid("B08FA8A2-B01A-4D2B-BD95-FEC7E30C5AEC"),
117 "b08fa8a2-b01a-4d2b-bd95-fec7e30c5aec"
118 );
119 }
120
121 #[test]
122 fn normalize_lowercase_uuid_unchanged() {
123 assert_eq!(
124 normalize_uuid("b08fa8a2-b01a-4d2b-bd95-fec7e30c5aec"),
125 "b08fa8a2-b01a-4d2b-bd95-fec7e30c5aec"
126 );
127 }
128
129 #[test]
130 fn normalize_invalid_returns_empty() {
131 assert_eq!(normalize_uuid(""), "");
132 assert_eq!(normalize_uuid("b08fa8a2"), "");
133 assert_eq!(normalize_uuid("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"), "");
134 }
135}