use std::path::{Path, PathBuf};
pub fn join_dir(dir: &str, file: &str) -> String {
let trimmed = dir.trim_end_matches(['/', '\\']);
Path::new(trimmed).join(file).to_string_lossy().into_owned()
}
#[cfg_attr(not(windows), allow(dead_code))]
pub fn with_exe_suffix(name: &str) -> String {
let lower = name.to_ascii_lowercase();
if lower.ends_with(".exe")
|| lower.ends_with(".dll")
|| lower.ends_with(".sys")
|| lower.ends_with(".com")
|| lower.ends_with(".efi")
|| Path::new(name).extension().is_some()
{
name.to_string()
} else {
format!("{name}.exe")
}
}
pub fn default_bin_rel(profile: &str, name: &str, triple_segment: Option<&str>) -> String {
let mut p = PathBuf::from("./target");
if let Some(t) = triple_segment {
p = p.join(t);
}
p.join(profile).join(name).to_string_lossy().into_owned()
}
pub fn default_lib_rel(profile: &str, file: &str, triple_segment: Option<&str>) -> String {
let mut p = PathBuf::from("./target");
if let Some(t) = triple_segment {
p = p.join(t);
}
p.join(profile).join(file).to_string_lossy().into_owned()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn join_dir_trims_both_slashes() {
assert_eq!(
join_dir("out/", "a"),
Path::new("out").join("a").to_string_lossy()
);
assert_eq!(
join_dir(r"out\", "a"),
Path::new("out").join("a").to_string_lossy()
);
}
#[test]
fn with_exe_no_double() {
assert_eq!(with_exe_suffix("hello"), "hello.exe");
assert_eq!(with_exe_suffix("hello.exe"), "hello.exe");
assert_eq!(with_exe_suffix("KERNEL.ELF"), "KERNEL.ELF");
assert_eq!(with_exe_suffix("x.dll"), "x.dll");
}
}