use anyhow::Result;
use std::path::{Path, PathBuf};
pub fn projects_root(override_dir: Option<&str>) -> Result<PathBuf> {
if let Some(d) = override_dir {
return Ok(PathBuf::from(d));
}
let home =
dirs::home_dir().ok_or_else(|| anyhow::anyhow!("cannot determine home directory"))?;
Ok(home.join(".claude").join("projects"))
}
pub fn resolve_target(path_arg: Option<&str>) -> Result<PathBuf> {
let raw = match path_arg {
Some(p) => PathBuf::from(p),
None => std::env::current_dir()?,
};
let abs = if raw.is_absolute() {
raw
} else {
std::env::current_dir()?.join(raw)
};
Ok(normalize(&abs))
}
fn normalize(p: &Path) -> PathBuf {
let mut out = PathBuf::new();
for comp in p.components() {
match comp {
std::path::Component::CurDir => {}
other => out.push(other.as_os_str()),
}
}
out
}
pub fn encode_path(path: &Path) -> String {
path.to_string_lossy().replace('/', "-")
}
pub fn dir_matches(encoded_target: &str, dir_name: &str, recursive: bool) -> bool {
if dir_name == encoded_target {
return true;
}
if recursive {
if let Some(rest) = dir_name.strip_prefix(encoded_target) {
return rest.starts_with('-');
}
}
false
}
pub fn path_under(target: &Path, cwd: &Path, recursive: bool) -> bool {
if cwd == target {
return true;
}
if recursive {
return cwd.starts_with(target);
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encode_path_replaces_slashes() {
assert_eq!(
encode_path(Path::new("/home/sibin/my-works")),
"-home-sibin-my-works"
);
}
#[test]
fn dir_matches_exact_and_child() {
let t = "-home-sibin-my-works";
assert!(dir_matches(t, "-home-sibin-my-works", true));
assert!(dir_matches(t, "-home-sibin-my-works-tiptestapp", true));
assert!(!dir_matches(t, "-home-sibin-other", true));
assert!(!dir_matches(t, "-home-sibin-my-works-tiptestapp", false));
}
#[test]
fn path_under_excludes_dashed_sibling() {
let target = Path::new("/home/sibin/my-works");
assert!(path_under(target, Path::new("/home/sibin/my-works"), true));
assert!(path_under(
target,
Path::new("/home/sibin/my-works/tiptestapp"),
true
));
assert!(!path_under(
target,
Path::new("/home/sibin/my-works-backup"),
true
));
assert!(!path_under(
target,
Path::new("/home/sibin/my-works/tiptestapp"),
false
));
}
}