1use std::path::{Path, PathBuf};
2
3pub fn expand_tilde(path: &Path) -> PathBuf {
7 let s = path.to_string_lossy();
8 if let Some(rest) = s.strip_prefix("~/") {
9 let home = dir_spec::home().expect("failed to resolve user's home directory");
10 home.join(rest)
11 } else if s == "~" {
12 dir_spec::home().expect("failed to resolve user's home directory")
13 } else {
14 path.to_path_buf()
15 }
16}
17
18#[cfg(test)]
19mod test {
20 use super::*;
21
22 mod expand_tilde {
23 use super::*;
24
25 #[test]
26 fn it_expands_bare_tilde() {
27 let result = expand_tilde(Path::new("~"));
28
29 assert!(result.is_absolute());
30 assert!(!result.to_string_lossy().contains('~'));
31 }
32
33 #[test]
34 fn it_expands_tilde_prefix() {
35 let result = expand_tilde(Path::new("~/Documents/file.txt"));
36
37 assert!(result.is_absolute());
38 assert!(result.ends_with("Documents/file.txt"));
39 }
40
41 #[test]
42 fn it_leaves_absolute_paths_unchanged() {
43 let path = Path::new("/usr/local/bin");
44 let result = expand_tilde(path);
45
46 assert_eq!(result, path);
47 }
48
49 #[test]
50 fn it_leaves_relative_paths_unchanged() {
51 let path = Path::new("relative/path");
52 let result = expand_tilde(path);
53
54 assert_eq!(result, path);
55 }
56 }
57}