Skip to main content

cli/
path_display.rs

1use std::path::Path;
2
3pub fn format(path: &Path) -> String {
4    normalize(&path.to_string_lossy())
5}
6
7pub fn format_home(path: &Path, home_dir: &Path) -> String {
8    match path.strip_prefix(home_dir) {
9        Ok(relative) if relative.as_os_str().is_empty() => "~".to_string(),
10        Ok(relative) => format!("~/{}", normalize(&relative.to_string_lossy())),
11        Err(_) => format(path),
12    }
13}
14
15pub fn format_tilde_path(path: &str, home_dir: &Path) -> String {
16    let expanded = crate::config::tilde_expand(path);
17    format_home(Path::new(&expanded), home_dir)
18}
19
20pub fn strip_windows_verbatim_prefix(value: &str) -> String {
21    value
22        .strip_prefix(r"\\?\UNC\")
23        .map(|path| format!(r"\\{path}"))
24        .or_else(|| value.strip_prefix(r"\\?\").map(str::to_string))
25        .unwrap_or_else(|| value.to_string())
26}
27
28fn normalize(value: &str) -> String {
29    strip_windows_verbatim_prefix(value).replace('\\', "/")
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35    use std::path::PathBuf;
36
37    #[test]
38    fn formats_paths_with_forward_slashes() {
39        assert_eq!(
40            format(Path::new(r"C:\Users\alice\file.txt")),
41            "C:/Users/alice/file.txt"
42        );
43    }
44
45    #[test]
46    fn strips_windows_verbatim_disk_prefix() {
47        assert_eq!(
48            format(Path::new(r"\\?\C:\Users\alice\file.txt")),
49            "C:/Users/alice/file.txt"
50        );
51    }
52
53    #[test]
54    fn strips_windows_verbatim_unc_prefix() {
55        assert_eq!(
56            format(Path::new(r"\\?\UNC\server\share\file.txt")),
57            "//server/share/file.txt"
58        );
59    }
60
61    #[test]
62    fn strips_windows_verbatim_prefix_without_changing_separators() {
63        assert_eq!(
64            strip_windows_verbatim_prefix(r"\\?\D:\Github\Biulight\shine\preset.ps1"),
65            r"D:\Github\Biulight\shine\preset.ps1"
66        );
67        assert_eq!(
68            strip_windows_verbatim_prefix(r"\\?\UNC\server\share\preset.ps1"),
69            r"\\server\share\preset.ps1"
70        );
71    }
72
73    #[test]
74    fn collapses_home_prefix() {
75        let home = PathBuf::from(r"C:\Users\alice");
76        let path = home.join("AppData").join("Roaming").join("Docker");
77        assert_eq!(format_home(&path, &home), "~/AppData/Roaming/Docker");
78    }
79
80    #[test]
81    fn formats_tilde_path_via_home_display_rules() {
82        let expanded = crate::config::tilde_expand("~/Library/Application Support");
83        let home = PathBuf::from(crate::config::tilde_expand("~"));
84        assert_eq!(
85            format_tilde_path("~/Library/Application Support", &home),
86            format_home(Path::new(&expanded), &home)
87        );
88    }
89}