use std::path::{Path, PathBuf};
pub fn expand_tilde(path: &str, home: &Path) -> PathBuf {
if path == "~" {
home.to_path_buf()
} else if let Some(rest) = path.strip_prefix("~/") {
home.join(rest)
} else {
PathBuf::from(path)
}
}
pub fn expand_tilde_env(path: &str) -> PathBuf {
match std::env::var("HOME") {
Ok(home) => expand_tilde(path, Path::new(&home)),
Err(_) => PathBuf::from(path),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_tilde_expands_against_home() {
let home = Path::new("/home/koala");
assert_eq!(expand_tilde("~", home), PathBuf::from("/home/koala"));
assert_eq!(
expand_tilde("~/models/a.gguf", home),
PathBuf::from("/home/koala/models/a.gguf")
);
}
#[test]
fn a_trailing_slash_on_home_is_normalized() {
assert_eq!(
expand_tilde("~/x", Path::new("/home/koala/")),
PathBuf::from("/home/koala/x")
);
}
#[test]
fn a_non_tilde_path_is_unchanged() {
let home = Path::new("/home/koala");
assert_eq!(expand_tilde("/abs/path", home), PathBuf::from("/abs/path"));
assert_eq!(expand_tilde("relative", home), PathBuf::from("relative"));
assert_eq!(expand_tilde("a/~/b", home), PathBuf::from("a/~/b"));
}
}