1use std::path::{Path, PathBuf};
4
5pub fn expand_tilde(path: &str, home: &Path) -> PathBuf {
8 if path == "~" {
9 home.to_path_buf()
10 } else if let Some(rest) = path.strip_prefix("~/") {
11 home.join(rest)
12 } else {
13 PathBuf::from(path)
14 }
15}
16
17pub fn expand_tilde_env(path: &str) -> PathBuf {
21 match std::env::var("HOME") {
22 Ok(home) => expand_tilde(path, Path::new(&home)),
23 Err(_) => PathBuf::from(path),
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30
31 #[test]
32 fn a_tilde_expands_against_home() {
33 let home = Path::new("/home/koala");
34 assert_eq!(expand_tilde("~", home), PathBuf::from("/home/koala"));
35 assert_eq!(
36 expand_tilde("~/models/a.gguf", home),
37 PathBuf::from("/home/koala/models/a.gguf")
38 );
39 }
40
41 #[test]
42 fn a_trailing_slash_on_home_is_normalized() {
43 assert_eq!(
44 expand_tilde("~/x", Path::new("/home/koala/")),
45 PathBuf::from("/home/koala/x")
46 );
47 }
48
49 #[test]
50 fn a_non_tilde_path_is_unchanged() {
51 let home = Path::new("/home/koala");
52 assert_eq!(expand_tilde("/abs/path", home), PathBuf::from("/abs/path"));
53 assert_eq!(expand_tilde("relative", home), PathBuf::from("relative"));
54 assert_eq!(expand_tilde("a/~/b", home), PathBuf::from("a/~/b"));
56 }
57}