use std::path::{Path, PathBuf};
use super::Space;
use crate::xdg::Env;
pub fn space_for(env: &Env, dir: &Path) -> Space {
if world_owned(env, dir) {
super::space(env)
} else {
Space::host(env)
}
}
pub fn world_owned(env: &Env, dir: &Path) -> bool {
real(dir).starts_with(real(&env.yog_data_root()))
}
fn real(p: &Path) -> PathBuf {
std::fs::canonicalize(p).unwrap_or_else(|_| p.to_path_buf())
}
#[cfg(test)]
mod tests {
use super::{space_for, world_owned};
use crate::world::marks::Space;
use crate::xdg::Env;
use std::path::Path;
fn world() -> Env {
crate::world::compose(&Env::from_pairs([
("HOME", "/home/u"),
("XDG_DATA_HOME", "/home/u/.local/share"),
("XDG_STATE_HOME", "/home/u/.local/state"),
("XDG_CONFIG_HOME", "/home/u/.config"),
]))
}
#[test]
fn a_world_owned_directory_resolves_the_worlds_space() {
let world = world();
let inside = Path::new("/home/u/.local/share/yog/world/litany/workspaces/alba");
assert!(world_owned(&world, inside));
assert_eq!(
space_for(&world, inside),
crate::world::marks::space(&world)
);
}
#[test]
fn an_operators_own_checkout_resolves_the_hosts_space() {
let world = world();
let outside = Path::new("/home/u/dev/proj");
assert!(!world_owned(&world, outside));
let space = space_for(&world, outside);
assert_eq!(space, Space::host(&world));
assert_eq!(space.state, Path::new("/home/u/.local/state"));
assert_eq!(space.config, Path::new("/home/u/.config"));
}
#[test]
fn an_own_marks_space_does_not_reach_an_operators_checkout() {
let agent = world().with_overrides(&[(
crate::world::marks::YOG_MARKS,
"/home/u/.local/share/yog/world/walls/alba/marks",
)]);
assert_eq!(
space_for(&agent, Path::new("/home/u/dev/proj")),
Space::host(&agent),
"the directory decides, not the visitor"
);
assert_eq!(
space_for(&agent, Path::new("/home/u/.local/share/yog/world/litany/x")),
Space::own(Path::new("/home/u/.local/share/yog/world/walls/alba/marks")),
"…and inside the world the agent's own space still decides"
);
}
}