fabro/lib/foundation/fabro-util/src/path.rs
2026-07-23 17:59:34 -04:00

54 lines
1.4 KiB
Rust

use std::path::{Path, PathBuf};
/// Expand `~/` prefix to the user's home directory.
pub fn expand_tilde(path: &Path) -> PathBuf {
if let Ok(rest) = path.strip_prefix("~") {
if let Some(home) = dirs::home_dir() {
return home.join(rest);
}
}
path.to_path_buf()
}
/// Replace the user's home directory prefix with `~` for display.
/// Returns the path unchanged if it is not under the home directory.
pub fn contract_tilde(path: &Path) -> PathBuf {
if let Some(home) = dirs::home_dir() {
if let Ok(rest) = path.strip_prefix(&home) {
return Path::new("~").join(rest);
}
}
path.to_path_buf()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn expand_tilde_with_home_prefix() {
let result = expand_tilde(Path::new("~/foo/bar"));
assert!(result != Path::new("~/foo/bar"));
assert!(result.ends_with("foo/bar"));
}
#[test]
fn expand_tilde_without_prefix() {
assert_eq!(expand_tilde(Path::new("/abs/path")), Path::new("/abs/path"));
}
#[test]
fn contract_tilde_under_home() {
let home = dirs::home_dir().unwrap();
let path = home.join("foo/bar");
assert_eq!(contract_tilde(&path), Path::new("~/foo/bar"));
}
#[test]
fn contract_tilde_outside_home() {
assert_eq!(
contract_tilde(Path::new("/tmp/other")),
Path::new("/tmp/other")
);
}
}