1use alloc::borrow::Cow;
4use std::path::{Component, Path};
5
6use crate::NormalizePath;
7
8pub trait DisplayPath {
10 fn opinionated_display(&self) -> String;
12}
13
14impl<P: AsRef<Path>> DisplayPath for P {
15 fn opinionated_display(&self) -> String {
16 display_path(self.as_ref())
17 }
18}
19
20pub fn display_path(path: &Path) -> String {
24 let path = path.normalized();
25
26 if path.as_path() == Path::new("") {
27 return ".".to_string();
28 }
29
30 let has_prefix = path
31 .components()
32 .next()
33 .is_some_and(|component| matches!(component, Component::Prefix(_)));
34
35 let separator = if has_prefix { r"\" } else { "/" };
36
37 path.components()
38 .filter_map(|component| {
39 if has_prefix && matches!(component, Component::RootDir) {
40 None
41 } else if matches!(component, Component::RootDir) {
42 Some(Cow::Borrowed(""))
43 } else {
44 Some(component.as_os_str().to_string_lossy())
45 }
46 })
47 .collect::<Vec<_>>()
48 .join(separator)
49}
50
51#[cfg(test)]
52mod test {
53 use std::path::Path;
54
55 use crate::display::DisplayPath;
56
57 #[test]
58 fn handles_relative() {
59 let expected = "some/relative/path/1";
60 let data = Path::new(r"some\relative\path\1");
61 assert_eq!(expected, data.opinionated_display());
62
63 let expected = "some/relative/path/2";
64 let data = Path::new(r".\some\relative\path\2");
65 assert_eq!(expected, data.opinionated_display());
66 }
67
68 #[test]
69 fn handles_windows_style() {
70 let expected = r"C:\some\absolute\path\1";
71 let data = Path::new(r"C:\some\absolute\path\1");
72 assert_eq!(expected, data.opinionated_display());
73
74 let expected = r"C:\some\absolute\path\2";
75 let data = Path::new(r"C:/some/absolute/path/2");
76 assert_eq!(expected, data.opinionated_display());
77 }
78
79 #[test]
80 fn handles_unix_style() {
81 let expected = r"/some/absolute/path/1";
82 let data = Path::new(r"/some/absolute/path/1");
83 assert_eq!(expected, data.opinionated_display());
84
85 let expected = r"/some/absolute/path/2";
86 let data = Path::new(r"\some\absolute\path\2");
87 assert_eq!(expected, data.opinionated_display());
88 }
89}