fallow_types/
path_util.rs1use std::path::{Component, Path};
14
15pub fn is_absolute_path_any_platform(path: &Path) -> bool {
21 if path.is_absolute() {
22 return true;
23 }
24 if matches!(path.components().next(), Some(Component::RootDir)) {
25 return true;
26 }
27 looks_like_windows_drive_absolute(path.as_os_str().as_encoded_bytes())
28}
29
30pub fn looks_like_windows_absolute_path(value: &str) -> bool {
35 looks_like_windows_drive_absolute(value.as_bytes())
36}
37
38fn looks_like_windows_drive_absolute(bytes: &[u8]) -> bool {
39 bytes.len() >= 3
40 && bytes[0].is_ascii_alphabetic()
41 && bytes[1] == b':'
42 && matches!(bytes[2], b'/' | b'\\')
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use std::path::PathBuf;
49
50 #[test]
51 fn posix_style_root_is_absolute_on_any_platform() {
52 assert!(is_absolute_path_any_platform(Path::new(
53 "/project/src/a.ts"
54 )));
55 assert!(is_absolute_path_any_platform(Path::new("/foo")));
56 assert!(is_absolute_path_any_platform(Path::new("/")));
57 }
58
59 #[test]
60 fn windows_drive_letter_is_absolute_on_any_platform() {
61 assert!(is_absolute_path_any_platform(Path::new(
62 "C:\\project\\src\\a.ts"
63 )));
64 assert!(is_absolute_path_any_platform(Path::new(
65 "C:/project/src/a.ts"
66 )));
67 assert!(is_absolute_path_any_platform(Path::new("d:/foo")));
68 }
69
70 #[test]
71 fn relative_paths_return_false() {
72 assert!(!is_absolute_path_any_platform(Path::new("src/a.ts")));
73 assert!(!is_absolute_path_any_platform(Path::new("./src/a.ts")));
74 assert!(!is_absolute_path_any_platform(Path::new("../parent/a.ts")));
75 assert!(!is_absolute_path_any_platform(Path::new("a.ts")));
76 assert!(!is_absolute_path_any_platform(Path::new("")));
77 }
78
79 #[cfg_attr(miri, ignore)]
80 #[test]
81 fn host_absolute_works_through_is_absolute() {
82 let cwd = std::env::current_dir().expect("current_dir");
83 assert!(is_absolute_path_any_platform(&cwd));
84 }
85
86 #[test]
87 fn looks_like_windows_absolute_path_recognises_drive_shapes() {
88 assert!(looks_like_windows_absolute_path("C:\\foo"));
89 assert!(looks_like_windows_absolute_path("c:/foo"));
90 assert!(looks_like_windows_absolute_path("Z:/very/deep/path.ts"));
91 assert!(!looks_like_windows_absolute_path("/foo"));
92 assert!(!looks_like_windows_absolute_path("src/foo"));
93 assert!(!looks_like_windows_absolute_path("C:"));
94 assert!(!looks_like_windows_absolute_path("CC:/foo"));
95 assert!(!looks_like_windows_absolute_path(""));
96 }
97
98 #[test]
99 fn drive_prefix_path_string_is_absolute_via_os_str_bytes() {
100 let p = PathBuf::from("E:/source/map.js");
101 assert!(is_absolute_path_any_platform(&p));
102 }
103}