runmat_runtime/builtins/common/
fs.rs1#[cfg(not(windows))]
8use crate::builtins::common::env as runtime_env;
9use std::cmp::Ordering;
10#[cfg(windows)]
11use std::env;
12use std::path::{Path, PathBuf};
13
14pub fn expand_user_path(raw: &str, error_prefix: &str) -> Result<String, String> {
18 if raw == "~" {
19 return home_directory()
20 .map(|path| path_to_string(&path))
21 .ok_or_else(|| format!("{error_prefix}: unable to resolve home directory"));
22 }
23
24 if let Some(stripped) = raw.strip_prefix("~/").or_else(|| raw.strip_prefix("~\\")) {
25 let home = home_directory()
26 .ok_or_else(|| format!("{error_prefix}: unable to resolve home directory"))?;
27 let mut buf = home;
28 if !stripped.is_empty() {
29 buf.push(stripped);
30 }
31 return Ok(path_to_string(&buf));
32 }
33
34 Ok(raw.to_string())
35}
36
37pub fn home_directory() -> Option<PathBuf> {
39 #[cfg(windows)]
40 {
41 if let Ok(user_profile) = env::var("USERPROFILE") {
42 return Some(PathBuf::from(user_profile));
43 }
44 if let (Ok(drive), Ok(path)) = (env::var("HOMEDRIVE"), env::var("HOMEPATH")) {
45 return Some(PathBuf::from(format!("{drive}{path}")));
46 }
47 None
48 }
49 #[cfg(not(windows))]
50 {
51 runtime_env::var("HOME").map(PathBuf::from).ok()
52 }
53}
54
55pub fn path_to_string(path: &Path) -> String {
57 path.to_string_lossy().into_owned()
58}
59
60pub fn contains_wildcards(text: &str) -> bool {
62 text.contains('*') || text.contains('?')
63}
64
65pub fn sort_entries(entries: &mut [String]) {
67 entries.sort_by(|a, b| compare_names(a, b));
68}
69
70pub fn compare_names(a: &str, b: &str) -> Ordering {
73 #[cfg(windows)]
74 {
75 let lower_a = a.to_ascii_lowercase();
76 let lower_b = b.to_ascii_lowercase();
77 match lower_a.cmp(&lower_b) {
78 Ordering::Equal => a.cmp(b),
79 other => other,
80 }
81 }
82 #[cfg(not(windows))]
83 {
84 a.cmp(b)
85 }
86}