crud_path/
common.rs

1use crate::DELIMITER;
2use path_clean::PathClean;
3use std::ffi::OsStr;
4use std::path::Path;
5
6pub(crate) fn exec<S, I>(cmd: S, args: I) -> bool
7where
8    I: IntoIterator<Item = S>,
9    S: AsRef<OsStr>,
10{
11    std::process::Command::new(cmd)
12        .envs(std::env::vars())
13        .args(args)
14        .output()
15        .is_ok()
16}
17
18pub fn get_path() -> Vec<String> {
19    let path = std::env::var("PATH")
20        .expect("Failed to get PATH")
21        .to_string();
22    path.split(DELIMITER)
23        .map(|s| s.replace("\\", "/").to_string())
24        .collect()
25}
26
27pub fn has_path(path: &str) -> bool {
28    let path = &expand_path(path);
29    #[cfg(windows)]
30    let path = to_win_path(path).replace("\\", "/");
31    get_path().iter().any(|i| i.eq_ignore_ascii_case(&path))
32}
33
34// c:/a/b -> C:\a\b
35pub fn to_win_path(path: &str) -> String {
36    let mut path = path.replace("/", "\\");
37    if let Some(s) = path.as_mut_str().get_mut(0..3)
38        && s.ends_with(":\\")
39    {
40        s.make_ascii_uppercase();
41    }
42    path
43}
44
45pub fn is_msys() -> bool {
46    std::env::var("MSYSTEM").is_ok()
47}
48
49// C:\a\b -> /c/a/b
50pub fn to_msys_path(path: &str) -> String {
51    let mut path = path.replace("\\", "/");
52    if let Some(s) = path.as_mut_str().get_mut(0..3)
53        && s.len() == 3
54        && s.ends_with(":/")
55    {
56        unsafe {
57            let p = s.as_mut_ptr();
58            let name = (*p).to_ascii_lowercase();
59            *p = b'/';
60            *(p.wrapping_add(1)) = name;
61            *(p.wrapping_add(2)) = b'/';
62        };
63    }
64    path
65}
66
67pub(crate) fn expand_path(path: &str) -> String {
68    let expanded = shellexpand::tilde(path);
69    Path::new(&*expanded).clean().to_string_lossy().to_string()
70}
71
72#[cfg(test)]
73mod test {
74    use super::get_path;
75
76    #[test]
77    fn test_get_path() {
78        let path = get_path();
79        assert!(!path.is_empty())
80    }
81}