//! Process-name matching for optional game-specific profile activation. //! //! Matching is explicit and opt-in: a profile supplies executable names, and //! only exact case-insensitive file-name matches activate it. use std::collections::HashSet; use sysinfo::System; use crate::profile_schema::Profile; pub fn running_executables() -> HashSet { let system = System::new_all(); system .processes() .values() .filter_map(|process| process.name().to_str()) .map(|name| name.to_ascii_lowercase()) .collect() } pub fn matching_profile_id(profiles: &[Profile]) -> Option { let running = running_executables(); profiles .iter() .filter(|profile| !profile.assigned_executables.is_empty()) .find(|profile| { profile .assigned_executables .iter() .any(|name| running.contains(&name.to_ascii_lowercase())) }) .map(|profile| profile.id.clone()) } #[cfg(test)] mod tests { use crate::default_profiles::{default_profile, fps_profile}; #[test] fn no_profiles_without_assignments_match() { let profiles = vec![default_profile(), fps_profile()]; assert!(profiles.iter().all(|p| p.assigned_executables.is_empty())); } }