diff --git a/src/directory.rs b/src/directory.rs index 61d09cf..2e2c412 100644 --- a/src/directory.rs +++ b/src/directory.rs @@ -78,6 +78,27 @@ impl Directory { } }; + let fold_op = |(mut size, mut children), dir| -> Result<(u64, Vec)> { + 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), (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) 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)> { - 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 - 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 { + /// TODO: maybe write directly to stdout to not use so much mem + fn vectorise(&self, unit: Unit) -> Vec { 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;