@@ -222,43 +222,59 @@ fn get_windows_path_var() -> Result<Option<String>> {
222
222
}
223
223
}
224
224
225
- pub fn do_remove_from_path ( methods : & [ PathUpdateMethod ] ) -> Result < ( ) > {
226
- assert ! ( methods. len( ) == 1 && methods[ 0 ] == PathUpdateMethod :: Windows ) ;
225
+ // Returns None if the existing old_path does not need changing
226
+ fn _remove_from_path ( old_path : & str , path_str : & str ) -> Option < String > {
227
+ let idx = old_path. find ( & path_str) ?;
228
+ // If there's a trailing semicolon (likely, since we probably added one
229
+ // during install), include that in the substring to remove. We don't search
230
+ // for that to find the string, because if its the last string in the path,
231
+ // there may not be.
232
+ let mut len = path_str. len ( ) ;
233
+ if old_path. as_bytes ( ) . get ( idx + path_str. len ( ) ) == Some ( & b';' ) {
234
+ len += 1 ;
235
+ }
227
236
228
- use std:: ptr;
229
- use winapi:: shared:: minwindef:: * ;
230
- use winapi:: um:: winuser:: {
231
- SendMessageTimeoutA , HWND_BROADCAST , SMTO_ABORTIFHUNG , WM_SETTINGCHANGE ,
232
- } ;
233
- use winreg:: enums:: { RegType , HKEY_CURRENT_USER , KEY_READ , KEY_WRITE } ;
234
- use winreg:: { RegKey , RegValue } ;
237
+ let mut new_path = old_path[ ..idx] . to_string ( ) ;
238
+ new_path. push_str ( & old_path[ idx + len..] ) ;
239
+ // Don't leave a trailing ; though, we don't want an empty string in the
240
+ // path.
241
+ if new_path. ends_with ( ';' ) {
242
+ new_path. pop ( ) ;
243
+ }
244
+ Some ( new_path)
245
+ }
235
246
247
+ fn _path_without_cargo_home_bin ( ) -> Result < Option < String > > {
236
248
let old_path = if let Some ( s) = get_windows_path_var ( ) ? {
237
249
s
238
250
} else {
239
251
// Non-unicode path
240
- return Ok ( ( ) ) ;
252
+ return Ok ( None ) ;
241
253
} ;
242
254
243
255
let path_str = utils:: cargo_home ( ) ?
244
256
. join ( "bin" )
245
257
. to_string_lossy ( )
246
258
. into_owned ( ) ;
247
- let idx = if let Some ( i) = old_path. find ( & path_str) {
248
- i
249
- } else {
250
- return Ok ( ( ) ) ;
251
- } ;
252
259
253
- // If there's a trailing semicolon (likely, since we added one during install),
254
- // include that in the substring to remove.
255
- let mut len = path_str. len ( ) ;
256
- if old_path. as_bytes ( ) . get ( idx + path_str. len ( ) ) == Some ( & b';' ) {
257
- len += 1 ;
258
- }
260
+ Ok ( _remove_from_path ( & old_path, & path_str) )
261
+ }
259
262
260
- let mut new_path = old_path[ ..idx] . to_string ( ) ;
261
- new_path. push_str ( & old_path[ idx + len..] ) ;
263
+ pub fn do_remove_from_path ( methods : & [ PathUpdateMethod ] ) -> Result < ( ) > {
264
+ assert ! ( methods. len( ) == 1 && methods[ 0 ] == PathUpdateMethod :: Windows ) ;
265
+
266
+ use std:: ptr;
267
+ use winapi:: shared:: minwindef:: * ;
268
+ use winapi:: um:: winuser:: {
269
+ SendMessageTimeoutA , HWND_BROADCAST , SMTO_ABORTIFHUNG , WM_SETTINGCHANGE ,
270
+ } ;
271
+ use winreg:: enums:: { RegType , HKEY_CURRENT_USER , KEY_READ , KEY_WRITE } ;
272
+ use winreg:: { RegKey , RegValue } ;
273
+
274
+ let new_path = match _path_without_cargo_home_bin ( ) ? {
275
+ Some ( new_path) => new_path,
276
+ None => return Ok ( ( ) ) , // No need to set the path
277
+ } ;
262
278
263
279
let root = RegKey :: predef ( HKEY_CURRENT_USER ) ;
264
280
let environment = root
@@ -430,3 +446,30 @@ pub fn get_add_path_methods() -> Vec<PathUpdateMethod> {
430
446
pub fn get_remove_path_methods ( ) -> Result < Vec < PathUpdateMethod > > {
431
447
Ok ( vec ! [ PathUpdateMethod :: Windows ] )
432
448
}
449
+
450
+ #[ cfg( test) ]
451
+ mod tests {
452
+ #[ test]
453
+ fn windows_uninstall_removes_semicolon_from_path_prefix ( ) {
454
+ assert_eq ! (
455
+ "foo" ,
456
+ super :: _remove_from_path(
457
+ r"c:\users\example\.cargo\bin;foo" ,
458
+ r"c:\users\example\.cargo\bin"
459
+ )
460
+ . unwrap( )
461
+ )
462
+ }
463
+
464
+ #[ test]
465
+ fn windows_uninstall_removes_semicolon_from_path_suffix ( ) {
466
+ assert_eq ! (
467
+ "foo" ,
468
+ super :: _remove_from_path(
469
+ r"foo;c:\users\example\.cargo\bin" ,
470
+ r"c:\users\example\.cargo\bin"
471
+ )
472
+ . unwrap( )
473
+ )
474
+ }
475
+ }
0 commit comments