Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/toolchain/src/lib.rs')
-rw-r--r--crates/toolchain/src/lib.rs43
1 files changed, 25 insertions, 18 deletions
diff --git a/crates/toolchain/src/lib.rs b/crates/toolchain/src/lib.rs
index a77fed585a..b577723612 100644
--- a/crates/toolchain/src/lib.rs
+++ b/crates/toolchain/src/lib.rs
@@ -2,10 +2,9 @@
#![warn(rust_2018_idioms, unused_lifetimes)]
-use std::{
- env, iter,
- path::{Path, PathBuf},
-};
+use std::{env, iter, path::PathBuf};
+
+use camino::{Utf8Path, Utf8PathBuf};
#[derive(Copy, Clone)]
pub enum Tool {
@@ -16,7 +15,7 @@ pub enum Tool {
}
impl Tool {
- pub fn proxy(self) -> Option<PathBuf> {
+ pub fn proxy(self) -> Option<Utf8PathBuf> {
cargo_proxy(self.name())
}
@@ -33,7 +32,7 @@ impl Tool {
/// example: for cargo, this tries all paths in $PATH with appended `cargo`, returning the
/// first that exists
/// 4) If all else fails, we just try to use the executable name directly
- pub fn prefer_proxy(self) -> PathBuf {
+ pub fn prefer_proxy(self) -> Utf8PathBuf {
invoke(&[cargo_proxy, lookup_as_env_var, lookup_in_path], self.name())
}
@@ -50,11 +49,11 @@ impl Tool {
/// example: for cargo, this tries $CARGO_HOME/bin/cargo, or ~/.cargo/bin/cargo if $CARGO_HOME is unset.
/// It seems that this is a reasonable place to try for cargo, rustc, and rustup
/// 4) If all else fails, we just try to use the executable name directly
- pub fn path(self) -> PathBuf {
+ pub fn path(self) -> Utf8PathBuf {
invoke(&[lookup_as_env_var, lookup_in_path, cargo_proxy], self.name())
}
- pub fn path_in(self, path: &Path) -> Option<PathBuf> {
+ pub fn path_in(self, path: &Utf8Path) -> Option<Utf8PathBuf> {
probe_for_binary(path.join(self.name()))
}
@@ -68,42 +67,50 @@ impl Tool {
}
}
-fn invoke(list: &[fn(&str) -> Option<PathBuf>], executable: &str) -> PathBuf {
+fn invoke(list: &[fn(&str) -> Option<Utf8PathBuf>], executable: &str) -> Utf8PathBuf {
list.iter().find_map(|it| it(executable)).unwrap_or_else(|| executable.into())
}
/// Looks up the binary as its SCREAMING upper case in the env variables.
-fn lookup_as_env_var(executable_name: &str) -> Option<PathBuf> {
- env::var_os(executable_name.to_ascii_uppercase()).map(Into::into)
+fn lookup_as_env_var(executable_name: &str) -> Option<Utf8PathBuf> {
+ env::var_os(executable_name.to_ascii_uppercase())
+ .map(PathBuf::from)
+ .map(Utf8PathBuf::try_from)
+ .and_then(Result::ok)
}
/// Looks up the binary in the cargo home directory if it exists.
-fn cargo_proxy(executable_name: &str) -> Option<PathBuf> {
+fn cargo_proxy(executable_name: &str) -> Option<Utf8PathBuf> {
let mut path = get_cargo_home()?;
path.push("bin");
path.push(executable_name);
probe_for_binary(path)
}
-fn get_cargo_home() -> Option<PathBuf> {
+fn get_cargo_home() -> Option<Utf8PathBuf> {
if let Some(path) = env::var_os("CARGO_HOME") {
- return Some(path.into());
+ return Utf8PathBuf::try_from(PathBuf::from(path)).ok();
}
if let Some(mut path) = home::home_dir() {
path.push(".cargo");
- return Some(path);
+ return Utf8PathBuf::try_from(path).ok();
}
None
}
-fn lookup_in_path(exec: &str) -> Option<PathBuf> {
+fn lookup_in_path(exec: &str) -> Option<Utf8PathBuf> {
let paths = env::var_os("PATH").unwrap_or_default();
- env::split_paths(&paths).map(|path| path.join(exec)).find_map(probe_for_binary)
+ env::split_paths(&paths)
+ .map(|path| path.join(exec))
+ .map(PathBuf::from)
+ .map(Utf8PathBuf::try_from)
+ .filter_map(Result::ok)
+ .find_map(probe_for_binary)
}
-pub fn probe_for_binary(path: PathBuf) -> Option<PathBuf> {
+pub fn probe_for_binary(path: Utf8PathBuf) -> Option<Utf8PathBuf> {
let with_extension = match env::consts::EXE_EXTENSION {
"" => None,
it => Some(path.with_extension(it)),