use crate::settings::file;
use std::collections::HashSet;
use std::error::Error;
use std::path::PathBuf;
use std::process::Command;
use configparser::ini;
use indexmap::map::IndexMap;
pub fn is_running(process_name: &str, print_pid: bool) -> bool {
let mut cmdline: Command = Command::new(String::from("pidof"));
cmdline.arg("--single-shot");
if !print_pid {
cmdline.arg("-q");
}
cmdline
.arg(process_name)
.status()
.expect("Could not execute `pidof` command.")
.success()
}
pub fn search_default_config() -> Option<PathBuf> {
let mut fullpath: PathBuf;
if let Ok(path) =
shellexpand::env("$XDG_CONFIG_HOME/retroarch/retroarch.cfg")
{
fullpath = PathBuf::from(path.to_string());
if fullpath.exists() {
return Some(fullpath);
}
}
fullpath = PathBuf::from(
shellexpand::tilde("~/.config/retroarch/retroarch.cfg").to_string(),
);
if fullpath.exists() {
return Some(fullpath);
}
fullpath =
PathBuf::from(shellexpand::tilde("~/.retroarch.cfg").to_string());
if fullpath.exists() {
return Some(fullpath);
}
None
}
pub fn parse_retroarch_config(
path: &Option<PathBuf>,
lookup_keys: &HashSet<String>,
) -> Result<IndexMap<String, String>, Box<dyn Error>> {
let mut ini = ini::Ini::new_cs();
match ini.load(
&path
.as_ref()
.expect("No configuration file.")
.display()
.to_string(),
) {
Ok(ini) => Ok(extract_default_inikeys(&ini, lookup_keys)),
Err(e) => Err(e.into()),
}
}
fn extract_default_inikeys(
ini: &IndexMap<String, IndexMap<String, Option<String>>>,
lookup_keys: &HashSet<String>,
) -> IndexMap<String, String> {
let mut found_keys: IndexMap<String, String> = IndexMap::new();
for (key, value) in ini
.get("default")
.unwrap()
.iter()
.filter(|(k, _)| lookup_keys.contains(k.as_str()))
.map(|(k, v)| (k.to_string(), v.as_ref().unwrap()))
{
found_keys.insert(key, value.trim_matches('"').to_string());
}
found_keys
}
pub fn libretro_fullpath(
directory: Option<PathBuf>,
libretro: Option<PathBuf>,
endswith: &str,
) -> Option<PathBuf> {
let mut fullpath: PathBuf = PathBuf::new();
if let Some(dir) = directory {
fullpath = file::tilde(&dir);
};
fullpath = fullpath.join(file::tilde(&libretro.unwrap_or_default()));
fullpath = file::endswith(endswith, fullpath);
file::to_fullpath(&fullpath)
}
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use configparser::ini;
use indexmap::map::IndexMap;
#[test]
fn is_running_cargo() {
assert_eq!(true, super::is_running("cargo", false));
}
#[test]
fn is_running_empty() {
assert_eq!(false, super::is_running("", false));
}
#[test]
fn extract_default_inikeys_single() {
let inidata: IndexMap<String, IndexMap<String, Option<String>>>;
inidata = ini::Ini::new()
.read(String::from(
"
video_vsync = \"true\"
libretro_directory = \"/home/user/.config/retroarch/cores\"
audio_device = \"\"
",
))
.expect("Could not create inidata.");
let mut lookup_keys: HashSet<String> = HashSet::new();
lookup_keys.insert("libretro_directory".to_string());
let found_keys =
super::extract_default_inikeys(&inidata, &lookup_keys);
assert_eq!(
"/home/user/.config/retroarch/cores".to_string(),
found_keys.get("libretro_directory").unwrap().to_string()
);
assert_eq!(None, found_keys.get("video_vsync"));
}
#[test]
fn extract_default_inikeys_multiple() {
let inidata: IndexMap<String, IndexMap<String, Option<String>>>;
inidata = ini::Ini::new()
.read(String::from(
"
video_vsync = \"true\"
libretro_directory = \"RamÃrez\"
libretro_directory = \"/home/user/.config/retroarch/cores\"
audio_device = \"\"
",
))
.expect("Could not create inidata.");
let mut lookup_keys: HashSet<String> = HashSet::new();
lookup_keys.insert("audio_device".to_string());
lookup_keys.insert("video_vsync".to_string());
lookup_keys.insert("libretro_directory".to_string());
let found_keys =
super::extract_default_inikeys(&inidata, &lookup_keys);
assert_eq!(
"".to_string(),
found_keys.get("audio_device").unwrap().to_string()
);
assert_eq!(
"true".to_string(),
found_keys.get("video_vsync").unwrap().to_string()
);
assert_eq!(
"/home/user/.config/retroarch/cores".to_string(),
found_keys.get("libretro_directory").unwrap().to_string()
);
}
}