treehouse/src/vfs/cd.rs

54 lines
1.3 KiB
Rust

use std::fmt;
use super::{entries, Dir, Entries, Query, VPath, VPathBuf};
pub struct Cd<T> {
parent: T,
path: VPathBuf,
}
impl<T> Cd<T> {
pub fn new(parent: T, path: VPathBuf) -> Self {
Self { parent, path }
}
}
impl<T> Cd<T>
where
T: Dir,
{
fn dir(&self, path: &VPath) -> Vec<VPathBuf> {
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<T> Dir for Cd<T>
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<T> fmt::Debug for Cd<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}/{:?}", self.parent, self.path)
}
}