1
1
/// Utilities for handling paths on ``rustic_core``
2
- use std:: borrow:: Cow ;
2
+ ///
3
+ use std:: { borrow:: Cow , ffi:: OsStr , path:: Path , str:: Utf8Error } ;
3
4
4
5
use globset:: GlobMatcher ;
5
6
use serde:: { Serialize , Serializer } ;
49
50
serializer. serialize_str ( & s)
50
51
}
51
52
52
- /// Converts a [`TypedPath`] to an [`Cow<UnixPath>`].
53
+ /// Converts a [`Path`] to a [`WindowsPath`].
54
+ ///
55
+ /// # Arguments
56
+ ///
57
+ /// * `path` - The path to convert.
58
+ ///
59
+ /// # Errors
60
+ ///
61
+ /// * If the path is non-unicode
62
+ pub fn path_to_windows_path ( path : & Path ) -> Result < & WindowsPath , Utf8Error > {
63
+ let str = std:: str:: from_utf8 ( path. as_os_str ( ) . as_encoded_bytes ( ) ) ?;
64
+ Ok ( WindowsPath :: new ( str) )
65
+ }
66
+
67
+ /// Converts a [`Path`] to a [`Cow<UnixPath>`].
68
+ ///
69
+ /// Note: On windows, this converts prefixes into unix paths, e.g. "C:\dir" into "/c/dir"
70
+ ///
71
+ /// # Arguments
72
+ ///
73
+ /// * `path` - The path to convert.
74
+ ///
75
+ /// # Errors
76
+ ///
77
+ /// * If the path is non-unicode and we are using windows
78
+ pub fn path_to_unix_path ( path : & Path ) -> Result < Cow < ' _ , UnixPath > , Utf8Error > {
79
+ #[ cfg( not( windows) ) ]
80
+ {
81
+ let path = UnixPath :: new ( path. as_os_str ( ) . as_encoded_bytes ( ) ) ;
82
+ Ok ( Cow :: Borrowed ( path) )
83
+ }
84
+ #[ cfg( windows) ]
85
+ {
86
+ let path = windows_path_to_unix_path ( path_to_windows_path ( path) ?) ;
87
+ Ok ( Cow :: Owned ( path) )
88
+ }
89
+ }
90
+
91
+ /// Converts a [`TypedPath`] to a [`Cow<Path>`].
92
+ ///
93
+ /// Note: On unix, this converts windows prefixes into unix paths, e.g. "C:\dir" into "/c/dir"
94
+ ///
95
+ /// # Arguments
96
+ ///
97
+ /// * `path` - The path to convert.
98
+ ///
99
+ /// # Errors
100
+ ///
101
+ /// * If the path is non-unicode and we are using windows
102
+ pub fn typed_path_to_path < ' a > ( path : & ' a TypedPath < ' a > ) -> Result < Cow < ' a , Path > , Utf8Error > {
103
+ #[ cfg( not( windows) ) ]
104
+ {
105
+ let path = match typed_path_to_unix_path ( path) {
106
+ Cow :: Borrowed ( path) => Cow :: Borrowed ( unix_path_to_path ( path) ?) ,
107
+ Cow :: Owned ( path) => Cow :: Owned ( unix_path_to_path ( & path) ?. to_path_buf ( ) ) ,
108
+ } ;
109
+ Ok ( path)
110
+ }
111
+ #[ cfg( windows) ]
112
+ {
113
+ // only utf8 items are allowed on windows
114
+ let str = std:: str:: from_utf8 ( path. as_bytes ( ) ) ?;
115
+ Ok ( Cow :: Borrowed ( Path :: new ( str) ) )
116
+ }
117
+ }
118
+
119
+ /// Converts a [`UnixPath`] to a [`Path`].
120
+ ///
121
+ /// # Arguments
122
+ ///
123
+ /// * `path` - The path to convert.
124
+ ///
125
+ /// # Errors
126
+ ///
127
+ /// * If the path is non-unicode and we are using windows
128
+ pub fn unix_path_to_path ( path : & UnixPath ) -> Result < & Path , Utf8Error > {
129
+ #[ cfg( not( windows) ) ]
130
+ {
131
+ let osstr: & OsStr = path. as_ref ( ) ;
132
+ Ok ( Path :: new ( osstr) )
133
+ }
134
+ #[ cfg( windows) ]
135
+ {
136
+ // only utf8 items are allowed on windows
137
+ let str = std:: str:: from_utf8 ( path. as_bytes ( ) ) ?;
138
+ Ok ( Path :: new ( str) )
139
+ }
140
+ }
141
+
142
+ /// Converts a [`TypedPath`] to a [`Cow<UnixPath>`].
53
143
///
54
144
/// # Arguments
55
145
///
@@ -64,6 +154,8 @@ pub fn typed_path_to_unix_path<'a>(path: &'a TypedPath<'_>) -> Cow<'a, UnixPath>
64
154
65
155
/// Converts a [`WindowsPath`] to a [`UnixPathBuf`].
66
156
///
157
+ /// Note: This converts windows prefixes into unix paths, e.g. "C:\dir" into "/c/dir"
158
+ ///
67
159
/// # Arguments
68
160
///
69
161
/// * `path` - The path to convert.
@@ -77,13 +169,13 @@ pub fn windows_path_to_unix_path(path: &WindowsPath) -> UnixPathBuf {
77
169
unix_path. push ( UnixComponent :: RootDir ) ;
78
170
match p. kind ( ) {
79
171
WindowsPrefix :: Verbatim ( p) | WindowsPrefix :: DeviceNS ( p) => {
80
- unix_path. push ( p) ;
172
+ unix_path. push ( p. to_ascii_lowercase ( ) ) ;
81
173
}
82
174
WindowsPrefix :: VerbatimUNC ( _, q) | WindowsPrefix :: UNC ( _, q) => {
83
- unix_path. push ( q) ;
175
+ unix_path. push ( q. to_ascii_lowercase ( ) ) ;
84
176
}
85
177
WindowsPrefix :: VerbatimDisk ( p) | WindowsPrefix :: Disk ( p) => {
86
- let c = vec ! [ p] ;
178
+ let c = vec ! [ p. to_ascii_lowercase ( ) ] ;
87
179
unix_path. push ( & c) ;
88
180
}
89
181
}
@@ -120,11 +212,12 @@ mod tests {
120
212
#[ case( r#"\"# , "/" ) ]
121
213
#[ case( "/test/test2" , "/test/test2" ) ]
122
214
#[ case( r#"\test\test2"# , "/test/test2" ) ]
123
- #[ case( r#"C:\"# , "/C" ) ]
124
- #[ case( r#"C:\dir"# , "/C/dir" ) ]
215
+ #[ case( r#"C:\"# , "/c" ) ]
216
+ #[ case( r#"C:\dir"# , "/c/dir" ) ]
217
+ #[ case( r#"d:\"# , "/d" ) ]
125
218
#[ case( r#"a\b\"# , "a/b" ) ]
126
219
#[ case( r#"a\b\c"# , "a/b/c" ) ]
127
- fn test_typed_path_to_unix_path ( #[ case] windows_path : & str , #[ case] unix_path : & str ) {
220
+ fn test_windows_path_to_unix_path ( #[ case] windows_path : & str , #[ case] unix_path : & str ) {
128
221
assert_eq ! (
129
222
windows_path_to_unix_path( WindowsPath :: new( windows_path) )
130
223
. to_str( )
0 commit comments