57 lines
1.4 KiB
Rust
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()
|
|
}
|
|
}
|
|
}
|