use std::path::PathBuf;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RustToolchain {
pub cargo_binary: PathBuf,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RustToolchainLoader {
cwd: PathBuf,
cached: Option<RustToolchain>,
}
impl Default for RustToolchainLoader {
fn default() -> Self {
Self::new(std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")))
}
}
impl RustToolchainLoader {
pub fn new(cwd: impl Into<PathBuf>) -> Self {
Self {
cwd: cwd.into(),
cached: None,
}
}
pub fn with_module_paths(cwd: impl Into<PathBuf>, _module_paths: Vec<PathBuf>) -> Self {
Self {
cwd: cwd.into(),
cached: None,
}
}
pub fn load(&mut self) -> Result<RustToolchain, String> {
if let Some(toolchain) = &self.cached {
return Ok(toolchain.clone());
}
let toolchain = self.resolve().unwrap_or_else(|| RustToolchain {
cargo_binary: PathBuf::from("cargo"),
});
self.cached = Some(toolchain.clone());
Ok(toolchain)
}
pub fn resolve(&self) -> Option<RustToolchain> {
let local = self
.cwd
.join(".cargo")
.join("bin")
.join(cargo_binary_name());
local.exists().then_some(RustToolchain {
cargo_binary: local,
})
}
pub fn get_module_paths(&self) -> Vec<PathBuf> {
vec![self.cwd.join(".cargo").join("bin")]
}
}
fn cargo_binary_name() -> &'static str {
if cfg!(windows) { "cargo.exe" } else { "cargo" }
}