entracte_lib/
proc_match.rs1pub fn process_match_lower(running_lower: &str, target_lower: &str) -> bool {
18 if target_lower.is_empty() {
19 return false;
20 }
21 let target_is_single_token = target_lower.chars().all(|c| c.is_alphanumeric());
22 if !target_is_single_token {
23 return running_lower.contains(target_lower);
24 }
25 running_lower
26 .split(|c: char| !c.is_alphanumeric())
27 .any(|tok| {
28 if tok == target_lower {
29 return true;
30 }
31 if let Some(suffix) = tok.strip_prefix(target_lower) {
32 !suffix.is_empty() && suffix.chars().all(|c| c.is_ascii_digit())
33 } else {
34 false
35 }
36 })
37}
38
39#[cfg(test)]
40mod tests {
41 use super::process_match_lower;
42
43 fn process_match(running: &str, target: &str) -> bool {
46 process_match_lower(&running.to_lowercase(), &target.to_lowercase())
47 }
48
49 #[test]
50 fn matches_whole_token() {
51 assert!(process_match("zoom.us", "zoom"));
52 assert!(process_match("OBS Studio", "obs"));
53 assert!(process_match("zoom", "zoom"));
54 assert!(process_match("Zoom Meeting Helper", "zoom"));
55 }
56
57 #[test]
58 fn rejects_substring_collisions() {
59 assert!(!process_match("zoominfo.exe", "zoom"));
60 assert!(!process_match("azoomatic", "zoom"));
61 assert!(!process_match("doomsday", "doom"));
62 }
63
64 #[test]
65 fn allows_digit_versioned_binaries() {
66 assert!(process_match("obs64.exe", "obs"));
67 assert!(process_match("OBS32.exe", "obs"));
68 assert!(process_match("firefox64.exe", "firefox"));
69 assert!(!process_match("firefoxnightly.exe", "firefox"));
70 }
71
72 #[test]
73 fn rejects_unrelated_apps() {
74 assert!(!process_match("safari", "zoom"));
75 assert!(!process_match("", "zoom"));
76 }
77
78 #[test]
79 fn falls_back_to_substring_for_multi_token_targets() {
80 assert!(process_match("/usr/bin/osascript -e foo", "osascript -e"));
81 assert!(!process_match("osascript", "osascript -e"));
82 }
83
84 #[test]
85 fn empty_target_never_matches() {
86 assert!(!process_match("zoom.us", ""));
87 assert!(!process_match("", ""));
88 }
89}