lechange_core/platform/
mod.rs1use std::path::MAIN_SEPARATOR;
4
5pub struct PathUtil;
7
8impl PathUtil {
9 #[inline]
11 pub fn normalize_separator(path: &str) -> String {
12 if cfg!(windows) {
13 path.replace('/', "\\")
14 } else {
15 path.replace('\\', "/")
16 }
17 }
18
19 #[inline]
21 pub const fn separator() -> char {
22 MAIN_SEPARATOR
23 }
24
25 #[inline]
27 pub fn has_separator(path: &str) -> bool {
28 path.contains('/') || path.contains('\\')
29 }
30
31 #[inline]
33 pub fn components(path: &str) -> impl Iterator<Item = &str> {
34 path.split(['/', '\\']).filter(|s| !s.is_empty())
35 }
36
37 #[inline]
41 pub fn to_posix(path: &str) -> std::borrow::Cow<'_, str> {
42 if cfg!(windows) || path.contains('\\') {
43 std::borrow::Cow::Owned(path.replace('\\', "/"))
44 } else {
45 std::borrow::Cow::Borrowed(path)
46 }
47 }
48
49 #[inline]
51 pub fn with_separator(path: &str, use_posix: bool) -> std::borrow::Cow<'_, str> {
52 if use_posix {
53 Self::to_posix(path)
54 } else {
55 std::borrow::Cow::Borrowed(path)
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_has_separator() {
66 assert!(PathUtil::has_separator("foo/bar"));
67 assert!(PathUtil::has_separator("foo\\bar"));
68 assert!(!PathUtil::has_separator("foo"));
69 }
70
71 #[test]
72 fn test_components() {
73 let parts: Vec<&str> = PathUtil::components("foo/bar/baz").collect();
74 assert_eq!(parts, vec!["foo", "bar", "baz"]);
75
76 let parts: Vec<&str> = PathUtil::components("foo\\bar\\baz").collect();
77 assert_eq!(parts, vec!["foo", "bar", "baz"]);
78 }
79
80 #[test]
81 fn test_normalize_separator() {
82 if !cfg!(windows) {
84 assert_eq!(PathUtil::normalize_separator("foo\\bar"), "foo/bar");
85 assert_eq!(PathUtil::normalize_separator("foo/bar"), "foo/bar");
86 }
87 }
88
89 #[test]
90 fn test_to_posix() {
91 let result = PathUtil::to_posix("foo\\bar\\baz");
92 assert_eq!(result.as_ref(), "foo/bar/baz");
93
94 if !cfg!(windows) {
96 let result = PathUtil::to_posix("foo/bar/baz");
97 assert!(matches!(result, std::borrow::Cow::Borrowed(_)));
98 assert_eq!(result.as_ref(), "foo/bar/baz");
99 }
100 }
101
102 #[test]
103 fn test_to_posix_no_backslash() {
104 let input = "already/posix/path";
105 let result = PathUtil::to_posix(input);
106 if !cfg!(windows) {
107 assert!(matches!(result, std::borrow::Cow::Borrowed(_)));
108 }
109 assert_eq!(result.as_ref(), "already/posix/path");
110 }
111
112 #[test]
113 fn test_with_separator_posix_true() {
114 let result = PathUtil::with_separator("foo\\bar", true);
115 assert_eq!(result.as_ref(), "foo/bar");
116 }
117
118 #[test]
119 fn test_with_separator_posix_false() {
120 let result = PathUtil::with_separator("foo\\bar", false);
121 assert!(matches!(result, std::borrow::Cow::Borrowed(_)));
123 assert_eq!(result.as_ref(), "foo\\bar");
124 }
125}