use super::{Classified, Effect, Root};
pub(super) fn move_to(path: &str, root: &Root) -> Classified {
let dest = root.resolve(path);
if root.holds(&dest) {
Classified::new(
Effect::Read,
format!("moves to {} inside the writable root", dest.display()),
)
} else {
Classified::new(
Effect::OpenWorld,
format!("moves to {}, outside the writable root", dest.display()),
)
}
}
pub(super) fn patch(envelope: &str, root: &Root) -> Classified {
let paths = patch_paths(envelope);
if root.holds_all(&paths) {
Classified::new(
Effect::TargetWrite,
"patches files inside the writable root",
)
} else {
Classified::new(
Effect::OpenWorld,
format!(
"patches {}, outside the writable root",
outside(&paths, root)
),
)
}
}
pub(super) fn outside(paths: &[String], root: &Root) -> String {
paths
.iter()
.find(|p| !root.holds(&root.resolve(p)))
.cloned()
.unwrap_or_default()
}
fn patch_paths(envelope: &str) -> Vec<String> {
const MARKERS: [&str; 4] = [
"*** Add File: ",
"*** Delete File: ",
"*** Update File: ",
"*** Move to: ",
];
envelope
.lines()
.filter_map(|line| {
MARKERS
.iter()
.find_map(|m| line.trim_end().strip_prefix(m))
.map(|p| p.trim().to_owned())
})
.filter(|p| !p.is_empty())
.collect()
}