use std::ffi::OsStr;
use std::path::PathBuf;
use crate::{constant::TOOLCHAIN_FILE, utils::trimmed_or_none};
pub fn resolve_toolchain_file() -> Option<PathBuf> {
let current_dir = std::env::current_dir().ok();
std::iter::successors(current_dir.as_deref(), |prev| prev.parent())
.find_map(|dir| Some(dir.join(TOOLCHAIN_FILE)).filter(|p| p.is_file()))
}
pub fn detect_pinned_toolchain() -> Option<String> {
resolve_toolchain_file()
.and_then(|path| {
std::fs::read_to_string(path)
.map(|s| trimmed_or_none(&s).map(str::to_owned))
.ok()
})
.flatten()
}
pub fn detect_default_toolchain() -> Option<String> {
let default_file = crate::moonup_home().join("default");
std::fs::read_to_string(default_file)
.map(|s| trimmed_or_none(&s).map(str::to_owned))
.ok()
.flatten()
}
pub fn detect_active_toolchain() -> PathBuf {
let active = detect_active_toolchainspec();
crate::moonup_home().join("toolchains").join(active)
}
pub fn detect_active_toolchainspec() -> String {
detect_pinned_toolchain()
.or(detect_default_toolchain())
.unwrap_or("latest".to_string())
}
pub fn resolve_exe<T, U>(binary_name: T, paths: U) -> Option<PathBuf>
where
T: AsRef<OsStr>,
U: AsRef<OsStr>,
{
which::which_in_global(binary_name, Some(paths))
.and_then(|mut i| i.next().ok_or(which::Error::CannotFindBinaryPath))
.ok()
}