use std::env;
use std::path::PathBuf;
pub fn agent_dir() -> PathBuf {
agent_dir_with(|name| env::var(name).ok())
}
pub fn agent_dir_with<F>(lookup: F) -> PathBuf
where
F: Fn(&str) -> Option<String>,
{
if let Some(raw) = lookup("CAPO_AGENT_DIR") {
return expand_tilde(&raw, &lookup);
}
if let Some(home) = lookup("HOME") {
return PathBuf::from(home).join(".capo").join("agent");
}
PathBuf::from(".capo").join("agent")
}
fn expand_tilde<F>(raw: &str, lookup: &F) -> PathBuf
where
F: Fn(&str) -> Option<String>,
{
let trimmed = raw.trim();
if trimmed == "~" {
return lookup("HOME")
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("~"));
}
if let Some(rest) = trimmed.strip_prefix("~/") {
if let Some(home) = lookup("HOME") {
return PathBuf::from(home).join(rest);
}
}
PathBuf::from(trimmed)
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
fn lookup(map: HashMap<&'static str, &'static str>) -> impl Fn(&str) -> Option<String> {
move |name| map.get(name).map(|v| (*v).to_string())
}
#[test]
fn agent_dir_uses_capo_agent_dir_env() {
let env = HashMap::from([("CAPO_AGENT_DIR", "/tmp/x")]);
assert_eq!(agent_dir_with(lookup(env)), PathBuf::from("/tmp/x"));
}
#[test]
fn agent_dir_expands_tilde_in_capo_agent_dir() {
let env = HashMap::from([("CAPO_AGENT_DIR", "~/.test-capo"), ("HOME", "/Users/wade")]);
assert_eq!(
agent_dir_with(lookup(env)),
PathBuf::from("/Users/wade/.test-capo")
);
}
#[test]
fn agent_dir_defaults_to_home_capo_agent() {
let env = HashMap::from([("HOME", "/Users/wade")]);
assert_eq!(
agent_dir_with(lookup(env)),
PathBuf::from("/Users/wade/.capo/agent")
);
}
}