use {
super::*,
directories::UserDirs,
ahash::AHashMap,
lazy_regex::*,
std::path::{Path, PathBuf},
};
pub fn path_from<P: AsRef<Path>>(
base_dir: P,
anchor: PathAnchor,
input: &str,
) -> PathBuf {
let tilde = regex!(r"^~(/|$)");
if input.starts_with('/') {
input.into()
} else if tilde.is_match(input) {
PathBuf::from(
&*tilde
.replace(input, |c: &Captures| {
if let Some(user_dirs) = UserDirs::new() {
format!(
"{}{}",
user_dirs.home_dir().to_string_lossy(),
&c[1],
)
} else {
warn!("no user dirs found, no expansion of ~");
c[0].to_string()
}
})
)
} else {
let base_dir = match anchor {
PathAnchor::Parent => base_dir
.as_ref()
.parent()
.unwrap_or_else(|| base_dir.as_ref())
.to_path_buf(),
_ => closest_dir(base_dir.as_ref()),
};
normalize_path(base_dir.join(input))
}
}
pub fn path_str_from<P: AsRef<Path>>(base_dir: P, input: &str) -> String {
path_from(base_dir, PathAnchor::Unspecified, input)
.to_string_lossy()
.to_string()
}
pub fn do_exec_replacement(
ec: &Captures<'_>,
replacement_map: &AHashMap<String, String>,
) -> String {
let name = ec.get(1).unwrap().as_str();
if let Some(repl) = replacement_map.get(name) {
if let Some(fmt) = ec.get(2) {
match fmt.as_str() {
"path-from-directory" => path_str_from(replacement_map.get("directory").unwrap(), repl),
"path-from-parent" => path_str_from(replacement_map.get("parent").unwrap(), repl),
_ => format!("invalid format: {:?}", fmt.as_str()),
}
} else {
repl.to_string()
}
} else {
format!("{{{}}}", name)
}
}