treehouse/src/vfs/overlay.rs
リキ萌 550c062327 factor out simple templates into a separate SimpleTemplateDir
there's no need to bloat TreehouseDir with that logic
2025-07-10 20:34:56 +02:00

57 lines
1.4 KiB
Rust

use std::fmt;
use tracing::instrument;
use crate::vfs::ToDynDir;
use super::{entries, Dir, DynDir, Entries, Query, VPath, VPathBuf};
pub struct Overlay {
base: DynDir,
overlay: DynDir,
}
impl Overlay {
pub fn new(base: DynDir, overlay: DynDir) -> Self {
Self { base, overlay }
}
#[instrument("Overlay::dir", skip(self))]
fn dir(&self, path: &VPath) -> Vec<VPathBuf> {
let mut dir = entries(&self.base, path);
dir.append(&mut entries(&self.overlay, path));
dir.sort();
dir.dedup();
dir
}
}
impl Dir for Overlay {
fn query(&self, path: &VPath, query: &mut Query) {
query.provide(|| Entries(self.dir(path)));
self.overlay.query(path, query);
self.base.query(path, query);
}
}
impl fmt::Debug for Overlay {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Overlay({:?}, {:?})", self.base, self.overlay)
}
}
pub fn layered_dir(layers: &[DynDir]) -> DynDir {
match layers {
[] => ().to_dyn(),
[dir] => dir.clone(),
[left, right] => Overlay::new(left.clone(), right.clone()).to_dyn(),
[left, right, rest @ ..] => {
let mut overlay = Overlay::new(left.clone(), right.clone());
for dir in rest {
overlay = Overlay::new(overlay.to_dyn(), dir.clone());
}
overlay.to_dyn()
}
}
}