#![cfg_attr(test, allow(clippy::expect_used, clippy::unwrap_used))]
use std::path::{Path, PathBuf};
use crate::error::{AppError, Result};
use crate::session::encode_cwd;
#[derive(Debug, Clone)]
pub struct SessionPaths {
pub agent_dir: PathBuf,
pub bucket_dir: PathBuf,
}
impl SessionPaths {
pub fn for_cwd(agent_dir: PathBuf, cwd: &Path) -> Self {
let bucket_dir = agent_dir.join("sessions").join(encode_cwd(cwd));
Self {
agent_dir,
bucket_dir,
}
}
pub fn ensure_bucket(&self) -> Result<()> {
std::fs::create_dir_all(&self.bucket_dir).map_err(|err| {
AppError::Config(format!(
"failed to create {}: {err}",
self.bucket_dir.display()
))
})
}
pub fn sessions_root(&self) -> PathBuf {
self.agent_dir.join("sessions")
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[test]
fn for_cwd_produces_encoded_bucket() {
let agent = PathBuf::from("/x/agent");
let cwd = PathBuf::from("/Users/wade/proj/capo");
let p = SessionPaths::for_cwd(agent.clone(), &cwd);
assert_eq!(p.agent_dir, agent);
assert_eq!(
p.bucket_dir,
PathBuf::from("/x/agent/sessions/--Users-wade-proj-capo--")
);
}
#[test]
fn ensure_bucket_creates_nested_dirs() {
let dir = tempdir().unwrap();
let p = SessionPaths::for_cwd(dir.path().to_path_buf(), &PathBuf::from("/tmp/x"));
assert!(!p.bucket_dir.exists());
p.ensure_bucket().unwrap();
assert!(p.bucket_dir.exists());
}
}