1
1
use std:: env;
2
2
use std:: ffi:: OsStr ;
3
+ #[ cfg( windows) ]
3
4
use std:: ffi:: OsString ;
4
5
use std:: path:: { Path , PathBuf } ;
5
6
use error:: * ;
6
- use helper:: check_extension;
7
-
8
7
#[ cfg( windows) ]
9
- lazy_static ! {
10
- static ref EXE_EXTENSION_VEC : Vec <String > = {
11
- // Read PATHEXT env variable and split it into vector of String
12
- let path_exts = env:: var_os( "PATHEXT" ) . unwrap_or( OsString :: from( env:: consts:: EXE_EXTENSION ) ) ;
13
- env:: split_paths( & path_exts)
14
- . map( |e| e. to_str( ) . map( |e| e. to_owned( ) ) )
15
- . filter_map( |e| e) . collect:: <Vec <_>>( )
16
- } ;
17
- }
8
+ use helper:: has_executable_extension;
18
9
19
10
pub trait Checker {
20
11
fn is_valid ( & self , path : & Path ) -> bool ;
@@ -43,13 +34,13 @@ impl Finder {
43
34
// Does it have a path separator?
44
35
if path. components ( ) . count ( ) > 1 {
45
36
if path. is_absolute ( ) {
46
- check_with_exe_extension ( path, binary_checker)
37
+ self . check_with_exe_extension ( path, binary_checker)
47
38
. ok_or ( ErrorKind :: BadAbsolutePath . into ( ) )
48
39
} else {
49
40
// Try to make it absolute.
50
41
let mut new_path = PathBuf :: from ( cwd. as_ref ( ) ) ;
51
42
new_path. push ( path) ;
52
- check_with_exe_extension ( new_path, binary_checker)
43
+ self . check_with_exe_extension ( new_path, binary_checker)
53
44
. ok_or ( ErrorKind :: BadRelativePath . into ( ) )
54
45
}
55
46
} else {
@@ -58,46 +49,57 @@ impl Finder {
58
49
. and_then ( |paths| {
59
50
env:: split_paths ( & paths)
60
51
. map ( |p| p. join ( binary_name. as_ref ( ) ) )
61
- . map ( |p| check_with_exe_extension ( p, binary_checker) )
52
+ . map ( |p| self . check_with_exe_extension ( p, binary_checker) )
62
53
. skip_while ( |res| res. is_none ( ) )
63
54
. next ( )
64
55
} )
65
56
. map ( |res| res. unwrap ( ) )
66
57
. ok_or ( ErrorKind :: CannotFindBinaryPath . into ( ) )
67
58
}
68
59
}
69
- }
70
60
71
- #[ cfg( unix) ]
72
- /// Check if given path with platform specification is valid
73
- pub fn check_with_exe_extension < T : AsRef < Path > > ( path : T , binary_checker : & Checker ) -> Option < PathBuf > {
74
- if binary_checker. is_valid ( & path) {
75
- Some ( path)
76
- } else {
77
- None
78
- }
79
- }
80
-
81
- #[ cfg( windows) ]
82
- /// Check if given path with platform specification is valid
83
- pub fn check_with_exe_extension < T : AsRef < Path > > ( path : T , binary_checker : & Checker ) -> Option < PathBuf > {
84
- // Check if path already have executable extension
85
- if check_extension ( & path, & EXE_EXTENSION_VEC ) {
61
+ #[ cfg( unix) ]
62
+ /// Check if given path with platform specification is valid
63
+ pub fn check_with_exe_extension < T : AsRef < Path > > ( & self , path : T , binary_checker : & Checker ) -> Option < PathBuf > {
86
64
if binary_checker. is_valid ( path. as_ref ( ) ) {
87
65
Some ( path. as_ref ( ) . to_path_buf ( ) )
88
66
} else {
89
67
None
90
68
}
91
- } else {
92
- // Check paths with windows executable extensions
93
- EXE_EXTENSION_VEC . iter ( )
94
- . map ( |e| {
95
- // Append the extension.
96
- let mut s = path. as_ref ( ) . to_path_buf ( ) . into_os_string ( ) ;
97
- s. push ( e) ;
98
- PathBuf :: from ( s)
99
- } )
100
- . skip_while ( |p| !( binary_checker. is_valid ( p) ) )
101
- . next ( )
69
+ }
70
+
71
+ #[ cfg( windows) ]
72
+ /// Check if given path with platform specification is valid
73
+ pub fn check_with_exe_extension < T : AsRef < Path > > ( & self , path : T , binary_checker : & Checker ) -> Option < PathBuf > {
74
+ // Read PATHEXT env variable and split it into vector of String
75
+ let path_exts = env:: var_os ( "PATHEXT" ) . unwrap_or ( OsString :: from ( env:: consts:: EXE_EXTENSION ) ) ;
76
+ let exe_extension_vec = env:: split_paths ( & path_exts)
77
+ . filter_map ( |e| e. to_str ( ) . map ( |e| e. to_owned ( ) ) )
78
+ . collect :: < Vec < _ > > ( ) ;
79
+
80
+ // Check if path already have executable extension
81
+ if has_executable_extension ( & path, & exe_extension_vec) {
82
+ if binary_checker. is_valid ( path. as_ref ( ) ) {
83
+ Some ( path. as_ref ( ) . to_path_buf ( ) )
84
+ } else {
85
+ None
86
+ }
87
+ } else {
88
+ // Check paths appended with windows executable extensions
89
+ // e.g. path `c:/windows/bin` will expend to:
90
+ // c:/windows/bin.COM
91
+ // c:/windows/bin.EXE
92
+ // c:/windows/bin.CMD
93
+ // ...
94
+ exe_extension_vec. iter ( )
95
+ . map ( |e| {
96
+ // Append the extension.
97
+ let mut s = path. as_ref ( ) . to_path_buf ( ) . into_os_string ( ) ;
98
+ s. push ( e) ;
99
+ PathBuf :: from ( s)
100
+ } )
101
+ . skip_while ( |p| !( binary_checker. is_valid ( p) ) )
102
+ . next ( )
103
+ }
102
104
}
103
105
}
0 commit comments