factored out closures, changed signature for vectorise

main
nick 2024-07-13 21:38:23 -04:00
parent 1828982270
commit 0c157927b8
1 changed files with 26 additions and 30 deletions

View File

@ -78,6 +78,27 @@ impl Directory {
}
};
let fold_op = |(mut size, mut children), dir| -> Result<(u64, Vec<Self>)> {
let dir: Self = match (dir, args.persistant()) {
(Ok(Some(d)), _) => d,
(Ok(None), _) | (Err(_), true) => return Ok((size, children)),
(Err(e), false) => return Err(e),
};
size += dir.size;
if args.tree() && args.should_print(dir.path()) {
// since size was increased, this just prevents
// the directory from appearing in printing
children.push(dir);
}
Ok((size, children))
};
let reduce_op = |(asize, mut avec): (u64, Vec<Self>), (bsize, bvec)| {
if args.tree() { avec.extend(bvec); }
Ok((asize + bsize, avec))
};
// this is a compicated iterator pattern. I'll do my best to explain.
// 1. the end result is that we `reduce()` the iterator to a single
// (u64, Vec<Directory>) tuple to return. this is done by...
@ -89,34 +110,10 @@ impl Directory {
.map(|entry| Self::new(entry?.path(), args))
// 4. the fold (this is try_fold because we're iterating over Result.).
// each fold adds a directory as a child and increases the total size
.try_fold(
|| (0, Vec::new()),
|(mut size, mut children), dir| -> Result<(u64, Vec<Self>)> {
let dir = match (dir, args.persistant()) {
(Ok(Some(d)), _) => d,
(Ok(None), _) | (Err(_), true) => return Result::Ok((size, children)),
(Err(e), false) => return Err(e),
};
size += dir.size;
if args.tree() && args.should_print(dir.path()) {
// since size was increased, this just prevents
// the directory from appearing in printing
children.push(dir);
}
// have to specify anyhow::Result::Ok otherwise it complains
// that it can't infer the E in Result<T, E>
Result::Ok((size, children))
}
)
.try_fold(|| (0, Vec::new()), fold_op)
// 5. the final step is to reduce, which is as simple as concatenating
// every vector and summing up their sizes.
.try_reduce(
|| (0, Vec::new()),
|(asize, mut avec), (bsize, bvec)| {
if args.tree() { avec.extend(bvec); }
Result::Ok((asize + bsize, avec))
}
) {
.try_reduce(|| (0, Vec::new()), reduce_op) {
// remember that this is a match statement?
Ok(tuple) => tuple,
Err(_) if args.persistant() => return Ok(None),
@ -155,9 +152,8 @@ impl Directory {
.unwrap_or_default()
}
/// TODO: make not recursive, take &self if possible,
/// and maybe write directly to stdout to not use so much mem
fn vectorise(self, unit: Unit) -> Vec<TreeEntry> {
/// TODO: maybe write directly to stdout to not use so much mem
fn vectorise(&self, unit: Unit) -> Vec<TreeEntry> {
let mut result = Vec::new();
result.push(TreeEntry::new(
@ -176,7 +172,7 @@ impl Directory {
// `wait` part. the last element of each one should however
// be introduced with a `last` part, and padding should with
// `blank`
for (idx, child) in self.children.into_iter().enumerate() {
for (idx, child) in self.children.iter().enumerate() {
if idx+1 == len {
new_entry_part = TreePart::Last;
continue_part = TreePart::Blank;