use std::cell::RefCell;
use std::path::{Path, PathBuf};
thread_local! {
static CWD_OVERRIDE: RefCell<Option<PathBuf>> = const { RefCell::new(None) };
}
pub fn run_with_cwd_override<T, F>(cwd: &Path, f: F) -> T
where
F: FnOnce() -> T,
{
CWD_OVERRIDE.with(|cell| {
let prev = cell.borrow().clone();
*cell.borrow_mut() = Some(cwd.to_path_buf());
let result = f();
*cell.borrow_mut() = prev;
result
})
}
pub fn pwd() -> PathBuf {
CWD_OVERRIDE
.with(|cell| cell.borrow().clone())
.unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from("/")))
}
pub fn get_cwd() -> PathBuf {
pwd()
}
pub fn get_original_cwd() -> PathBuf {
std::env::current_dir().unwrap_or_else(|_| PathBuf::from("/"))
}
pub fn set_cwd(path: &Path) {
CWD_OVERRIDE.with(|cell| {
*cell.borrow_mut() = Some(path.to_path_buf());
});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pwd_returns_current_dir() {
let cwd = pwd();
assert!(cwd.is_absolute());
}
#[test]
fn test_run_with_cwd_override() {
let original = pwd();
let test_dir = PathBuf::from("/tmp/test_cwd");
run_with_cwd_override(&test_dir, || {
assert_eq!(pwd(), test_dir);
});
assert_eq!(pwd(), original);
}
}