1#[must_use]
5pub fn normalize_slashes(path: &str) -> String {
6 if path.contains('\\') {
7 path.replace('\\', "/")
8 } else {
9 path.to_string()
10 }
11}
12
13#[must_use]
17pub fn normalize_rel_path(path: &str) -> String {
18 let normalized = normalize_slashes(path);
19 if let Some(stripped) = normalized.strip_prefix("./") {
20 stripped.to_string()
21 } else {
22 normalized
23 }
24}
25
26#[cfg(test)]
27mod tests {
28 use super::*;
29 use proptest::prelude::*;
30
31 #[test]
32 fn normalize_slashes_replaces_backslash() {
33 assert_eq!(normalize_slashes(r"foo\bar\baz.rs"), "foo/bar/baz.rs");
34 }
35
36 #[test]
37 fn normalize_rel_path_strips_dot_slash() {
38 assert_eq!(normalize_rel_path("./src/main.rs"), "src/main.rs");
39 }
40
41 #[test]
42 fn normalize_rel_path_strips_dot_backslash() {
43 assert_eq!(normalize_rel_path(r".\src\main.rs"), "src/main.rs");
44 }
45
46 #[test]
47 fn normalize_rel_path_preserves_non_relative_prefix() {
48 assert_eq!(normalize_rel_path("../src/main.rs"), "../src/main.rs");
49 }
50
51 proptest! {
52 #[test]
53 fn normalize_slashes_no_backslashes(path in "\\PC*") {
54 let normalized = normalize_slashes(&path);
55 prop_assert!(!normalized.contains('\\'));
56 }
57
58 #[test]
59 fn normalize_slashes_idempotent(path in "\\PC*") {
60 let once = normalize_slashes(&path);
61 let twice = normalize_slashes(&once);
62 prop_assert_eq!(once, twice);
63 }
64
65 #[test]
66 fn normalize_rel_path_no_backslashes(path in "\\PC*") {
67 let normalized = normalize_rel_path(&path);
68 prop_assert!(!normalized.contains('\\'));
69 }
70
71 #[test]
72 fn normalize_rel_path_idempotent(path in "\\PC*") {
73 let once = normalize_rel_path(&path);
74 let twice = normalize_rel_path(&once);
75 prop_assert_eq!(once, twice);
76 }
77 }
78}