#[cfg(not(windows))]
use crate::builtins::common::env as runtime_env;
use std::cmp::Ordering;
#[cfg(windows)]
use std::env;
use std::path::{Path, PathBuf};
pub fn expand_user_path(raw: &str, error_prefix: &str) -> Result<String, String> {
if raw == "~" {
return home_directory()
.map(|path| path_to_string(&path))
.ok_or_else(|| format!("{error_prefix}: unable to resolve home directory"));
}
if let Some(stripped) = raw.strip_prefix("~/").or_else(|| raw.strip_prefix("~\\")) {
let home = home_directory()
.ok_or_else(|| format!("{error_prefix}: unable to resolve home directory"))?;
let mut buf = home;
if !stripped.is_empty() {
buf.push(stripped);
}
return Ok(path_to_string(&buf));
}
Ok(raw.to_string())
}
pub fn home_directory() -> Option<PathBuf> {
#[cfg(windows)]
{
if let Ok(user_profile) = env::var("USERPROFILE") {
return Some(PathBuf::from(user_profile));
}
if let (Ok(drive), Ok(path)) = (env::var("HOMEDRIVE"), env::var("HOMEPATH")) {
return Some(PathBuf::from(format!("{drive}{path}")));
}
None
}
#[cfg(not(windows))]
{
runtime_env::var("HOME").map(PathBuf::from).ok()
}
}
pub fn path_to_string(path: &Path) -> String {
path.to_string_lossy().into_owned()
}
pub fn contains_wildcards(text: &str) -> bool {
text.contains('*') || text.contains('?')
}
pub fn sort_entries(entries: &mut [String]) {
entries.sort_by(|a, b| compare_names(a, b));
}
pub fn compare_names(a: &str, b: &str) -> Ordering {
#[cfg(windows)]
{
let lower_a = a.to_ascii_lowercase();
let lower_b = b.to_ascii_lowercase();
match lower_a.cmp(&lower_b) {
Ordering::Equal => a.cmp(b),
other => other,
}
}
#[cfg(not(windows))]
{
a.cmp(b)
}
}