54 lines
1.3 KiB
Rust
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)
|
|
}
|
|
}
|