1use std::path::{Path, PathBuf};
2use std::process;
3
4use super::output::*;
5
6pub fn path_as_string(path: &Path) -> String {
7 path.to_path_buf().into_os_string().into_string().unwrap()
8}
9
10pub fn env_home() -> String {
11 match std::env::var("HOME") {
12 Ok(path) => path,
13 Err(error) => {
14 print_error(&format!("Unable to read HOME: {error}"));
15 process::exit(1);
16 }
17 }
18}
19
20pub fn expand_path(path: &Path) -> PathBuf {
21 let expanded_path = match shellexpand::full_with_context(
22 &path_as_string(path),
23 || Some(env_home()),
24 |name| -> Result<Option<String>, &'static str> {
25 match name {
26 "HOME" => Ok(Some(env_home())),
27 _ => Ok(None),
28 }
29 },
30 ) {
31 Ok(std::borrow::Cow::Borrowed(path)) => path.to_owned(),
32 Ok(std::borrow::Cow::Owned(path)) => path,
33 Err(error) => {
34 print_error(&format!("Unable to expand root: {error}"));
35 process::exit(1);
36 }
37 };
38
39 Path::new(&expanded_path).to_path_buf()
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 fn setup() {
47 std::env::set_var("HOME", "/home/test");
48 }
49
50 #[test]
51 fn check_expand_tilde() {
52 setup();
53 assert_eq!(
54 expand_path(Path::new("~/file")),
55 Path::new("/home/test/file")
56 );
57 }
58
59 #[test]
60 fn check_expand_invalid_tilde() {
61 setup();
62 assert_eq!(
63 expand_path(Path::new("/home/~/file")),
64 Path::new("/home/~/file")
65 );
66 }
67
68 #[test]
69 fn check_expand_home() {
70 setup();
71 assert_eq!(
72 expand_path(Path::new("$HOME/file")),
73 Path::new("/home/test/file")
74 );
75 assert_eq!(
76 expand_path(Path::new("${HOME}/file")),
77 Path::new("/home/test/file")
78 );
79 }
80}