use std::os::unix::prelude::OsStrExt;
use async_std::path::{Path, PathBuf};
use path_absolutize::Absolutize;
pub fn resolve_path(base_path: &Path, file_path: &Path) -> PathBuf {
let first_char = file_path.as_os_str().as_bytes()[0];
if first_char == b'/' {
PathBuf::from(file_path)
} else if first_char == b'~' {
let home_dir = PathBuf::from(dirs::home_dir().unwrap());
let path_str = file_path.to_str().unwrap();
home_dir.join(&path_str[1..])
} else {
type StdPath = std::path::Path;
let z = StdPath::new(file_path)
.absolutize_from(StdPath::new(base_path))
.unwrap();
match z {
std::borrow::Cow::Owned(z) => PathBuf::from(z),
std::borrow::Cow::Borrowed(z) => PathBuf::from(z),
}
}
}
pub fn is_empty_root_url(p: &str) -> bool {
if p.len() > 1 {
return false;
}
p.chars().next().map(|c| c == '/').unwrap_or(true)
}
#[test]
fn test_resolve_path() {
let home = PathBuf::from(dirs::home_dir().unwrap());
let cwd = PathBuf::from("/pa/pb/pc/");
assert_eq!(
"/a/b/c",
resolve_path(&cwd, &PathBuf::from("/a/b/c"))
.to_str()
.unwrap()
);
assert_eq!(
home.join("a/b/c"),
resolve_path(&cwd, &PathBuf::from("~a/b/c"))
);
assert_eq!(
cwd.join("a/b/c"),
resolve_path(&cwd, &PathBuf::from("a/b/c"))
);
assert_eq!(
cwd.join("a/b/c"),
resolve_path(&cwd, &PathBuf::from("./a/b/c"))
);
assert_eq!(
"/pa/pb/a/b/c",
resolve_path(&cwd, &PathBuf::from("../a/b/c"))
.to_str()
.unwrap()
);
assert_eq!(
"/pa/a/b/c",
resolve_path(&cwd, &PathBuf::from("../../a/b/c"))
.to_str()
.unwrap()
);
assert_eq!(
"/a/b/c",
resolve_path(&cwd, &PathBuf::from("../../../a/b/c"))
.to_str()
.unwrap()
);
assert_eq!(
"/a/b/c",
resolve_path(&cwd, &PathBuf::from("../../../../a/b/c"))
.to_str()
.unwrap()
);
}