use crate::{Error::*, Result};
use dirs;
use std::{
fs::{self},
path::{Path, PathBuf},
};
fn validate_dir(dir: PathBuf) -> Result<PathBuf> {
if dir.try_exists()? {
Ok(dir)
} else {
fs::create_dir_all(&dir)?;
Ok(dir)
}
}
pub fn beamng_dir(possible_dirs: impl Iterator<Item = PathBuf>) -> Result<PathBuf> {
possible_dirs
.map(|d| d.join("BeamNG.drive"))
.find(|d| d.try_exists().unwrap_or(false)) .ok_or(GameDirNotFound)
}
#[cfg_attr(coverage_nightly, coverage(off))]
pub fn beamng_dir_default() -> Result<PathBuf> {
let possible_dirs = vec![dirs::data_local_dir(), dirs::data_dir()]
.into_iter()
.flatten();
beamng_dir(possible_dirs)
}
pub fn mods_dir(data_dir: &Path, version: &str) -> Result<PathBuf> {
if !data_dir.try_exists()? {
Err(DirNotFound {
dir: data_dir.to_owned(),
})
} else {
let mods_dir_ = data_dir.join(version).join("mods");
if mods_dir_.try_exists()? {
Ok(mods_dir_)
} else {
Err(DirNotFound { dir: mods_dir_ })
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
pub fn beammm_dir() -> Result<PathBuf> {
let dir = dirs::data_local_dir()
.ok_or(MissingLocalAppdata)?
.join("BeamMM");
validate_dir(dir)
}
#[cfg_attr(coverage_nightly, coverage(off))]
pub fn presets_dir(beammm_dir: &Path) -> Result<PathBuf> {
let dir = beammm_dir.join("presets");
validate_dir(dir)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_dir() {
let tmp = tempfile::tempdir().unwrap();
let temp_dir = tmp.path();
let exists = temp_dir.join("exists");
fs::create_dir(&exists).unwrap();
assert_eq!(validate_dir(exists.clone()).unwrap(), exists);
let not_exists = temp_dir.join("not_exists");
assert_eq!(validate_dir(not_exists.clone()).unwrap(), not_exists);
assert!(not_exists.exists());
}
#[test]
fn test_beamng_dir() {
let tmp = tempfile::tempdir().unwrap();
let temp_dir = tmp.path();
let with_beamng = temp_dir.join("with_beamng");
fs::create_dir(&with_beamng).unwrap();
let with_beamng_drive = with_beamng.join("BeamNG.drive");
fs::create_dir(&with_beamng_drive).unwrap();
let without_beamng = temp_dir.join("without_beamng");
fs::create_dir(&without_beamng).unwrap();
assert_eq!(
beamng_dir(vec![with_beamng.clone(), without_beamng.clone()].into_iter()).unwrap(),
with_beamng_drive
);
assert!(matches!(
beamng_dir(vec![without_beamng.clone()].into_iter()).unwrap_err(),
GameDirNotFound
));
}
#[test]
fn test_mods_dir() {
let not_exists = PathBuf::from("not_exists");
let version = "0.32";
let tmp = tempfile::tempdir().unwrap();
let data_dir = tmp.path();
let version_dir = data_dir.join(version);
fs::create_dir(&version_dir).unwrap();
assert!(matches!(
mods_dir(¬_exists, version).unwrap_err(),
DirNotFound { .. }
));
assert!(matches!(
mods_dir(data_dir, version).unwrap_err(),
DirNotFound { .. }
));
let mods_dir_path = version_dir.join("mods");
fs::create_dir(&mods_dir_path).unwrap();
assert_eq!(mods_dir(data_dir, version).unwrap(), mods_dir_path);
}
}