use std::fmt; use super::{entries, Dir, Entries, Query, VPath, VPathBuf}; pub struct Cd { parent: T, path: VPathBuf, } impl Cd { pub fn new(parent: T, path: VPathBuf) -> Self { Self { parent, path } } } impl Cd where T: Dir, { fn dir(&self, path: &VPath) -> Vec { entries(&self.parent, &self.path.join(path)) .into_iter() .map(|entry| { entry .strip_prefix(&self.path) .expect("all entries must be anchored within `self.path`") .to_owned() }) .collect() } } impl Dir for Cd where T: Dir, { fn query(&self, path: &VPath, query: &mut Query) { // The only query that meaningfully needs to return something else is `dir`, which must // be modified to strip prefixes off of the parent's returned paths. query.provide(|| Entries(self.dir(path))); // Other queries can run unmodified, only passing them the right path. self.parent.query(&self.path.join(path), query); } } impl fmt::Debug for Cd where T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}/{:?}", self.parent, self.path) } }