aboutsummaryrefslogtreecommitdiff
path: root/src/finder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/finder.rs')
-rw-r--r--src/finder.rs104
1 files changed, 26 insertions, 78 deletions
diff --git a/src/finder.rs b/src/finder.rs
index 43b659d..91c6cab 100644
--- a/src/finder.rs
+++ b/src/finder.rs
@@ -1,16 +1,12 @@
use crate::checker::CompositeChecker;
use crate::error::*;
+use either::Either;
#[cfg(windows)]
use crate::helper::has_executable_extension;
-use either::Either;
-#[cfg(feature = "regex")]
-use regex::Regex;
-#[cfg(feature = "regex")]
-use std::borrow::Borrow;
use std::env;
use std::ffi::OsStr;
-#[cfg(feature = "regex")]
-use std::fs;
+#[cfg(windows)]
+use std::ffi::OsString;
use std::iter;
use std::path::{Path, PathBuf};
@@ -56,7 +52,7 @@ impl Finder {
&self,
binary_name: T,
paths: Option<U>,
- cwd: Option<V>,
+ cwd: V,
binary_checker: CompositeChecker,
) -> Result<impl Iterator<Item = PathBuf>>
where
@@ -66,54 +62,20 @@ impl Finder {
{
let path = PathBuf::from(&binary_name);
- let binary_path_candidates = match cwd {
- Some(cwd) if path.has_separator() => {
- // Search binary in cwd if the path have a path separator.
- Either::Left(Self::cwd_search_candidates(path, cwd).into_iter())
- }
- _ => {
- // Search binary in PATHs(defined in environment variable).
- let p = paths.ok_or(Error::CannotFindBinaryPath)?;
- let paths: Vec<_> = env::split_paths(&p).collect();
-
- Either::Right(Self::path_search_candidates(path, paths).into_iter())
- }
+ let binary_path_candidates = if path.has_separator() {
+ // Search binary in cwd if the path have a path separator.
+ Either::Left(Self::cwd_search_candidates(path, cwd).into_iter())
+ } else {
+ // Search binary in PATHs(defined in environment variable).
+ let p = paths.ok_or(Error::CannotFindBinaryPath)?;
+ let paths: Vec<_> = env::split_paths(&p).collect();
+
+ Either::Right(Self::path_search_candidates(path, paths).into_iter())
};
Ok(binary_path_candidates.filter(move |p| binary_checker.is_valid(p)))
}
- #[cfg(feature = "regex")]
- pub fn find_re<T>(
- &self,
- binary_regex: impl Borrow<Regex>,
- paths: Option<T>,
- binary_checker: CompositeChecker,
- ) -> Result<impl Iterator<Item = PathBuf>>
- where
- T: AsRef<OsStr>,
- {
- let p = paths.ok_or(Error::CannotFindBinaryPath)?;
- let paths: Vec<_> = env::split_paths(&p).collect();
-
- let matching_re = paths
- .into_iter()
- .flat_map(fs::read_dir)
- .flatten()
- .flatten()
- .map(|e| e.path())
- .filter(move |p| {
- if let Some(unicode_file_name) = p.file_name().unwrap().to_str() {
- binary_regex.borrow().is_match(unicode_file_name)
- } else {
- false
- }
- })
- .filter(move |p| binary_checker.is_valid(p));
-
- Ok(matching_re)
- }
-
fn cwd_search_candidates<C>(binary_name: PathBuf, cwd: C) -> impl IntoIterator<Item = PathBuf>
where
C: AsRef<Path>,
@@ -148,35 +110,19 @@ impl Finder {
where
P: IntoIterator<Item = PathBuf>,
{
- // Sample %PATHEXT%: .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
- // PATH_EXTENSIONS is then [".COM", ".EXE", ".BAT", …].
- // (In one use of PATH_EXTENSIONS we skip the dot, but in the other we need it;
- // hence its retention.)
- lazy_static! {
- static ref PATH_EXTENSIONS: Vec<String> =
- env::var("PATHEXT")
- .map(|pathext| {
- pathext.split(';')
- .filter_map(|s| {
- if s.as_bytes().first() == Some(&b'.') {
- Some(s.to_owned())
- } else {
- // Invalid segment; just ignore it.
- None
- }
- })
- .collect()
- })
- // PATHEXT not being set or not being a proper Unicode string is exceedingly
- // improbable and would probably break Windows badly. Still, don't crash:
- .unwrap_or(vec![]);
- }
+ // Read PATHEXT env variable and split it into vector of String
+ let path_exts =
+ env::var_os("PATHEXT").unwrap_or(OsString::from(env::consts::EXE_EXTENSION));
+
+ let exe_extension_vec = env::split_paths(&path_exts)
+ .filter_map(|e| e.to_str().map(|e| e.to_owned()))
+ .collect::<Vec<_>>();
paths
.into_iter()
.flat_map(move |p| -> Box<dyn Iterator<Item = _>> {
// Check if path already have executable extension
- if has_executable_extension(&p, &PATH_EXTENSIONS) {
+ if has_executable_extension(&p, &exe_extension_vec) {
Box::new(iter::once(p))
} else {
// Appended paths with windows executable extensions.
@@ -185,13 +131,15 @@ impl Finder {
// c:/windows/bin.EXE
// c:/windows/bin.CMD
// ...
- Box::new(PATH_EXTENSIONS.iter().map(move |e| {
+ let ps = exe_extension_vec.clone().into_iter().map(move |e| {
// Append the extension.
- let mut p = p.clone().into_os_string();
+ let mut p = p.clone().to_path_buf().into_os_string();
p.push(e);
PathBuf::from(p)
- }))
+ });
+
+ Box::new(ps)
}
})
}