From b8a77c43b3606e3a04174d0a7599e59d5d39c8a4 Mon Sep 17 00:00:00 2001 From: Philippe-Cholet Date: Mon, 2 Oct 2023 11:10:24 +0200 Subject: [PATCH] `WithPosition::fold` --- src/with_position.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/with_position.rs b/src/with_position.rs index 58802c5ff..89cddeb8a 100644 --- a/src/with_position.rs +++ b/src/with_position.rs @@ -81,6 +81,33 @@ impl Iterator for WithPosition { fn size_hint(&self) -> (usize, Option) { self.peekable.size_hint() } + + fn fold(mut self, mut init: B, mut f: F) -> B + where + F: FnMut(B, Self::Item) -> B, + { + if let Some(mut head) = self.peekable.next() { + if !self.handled_first { + // The current head is `First` or `Only`, + // it depends if there is another item or not. + match self.peekable.next() { + Some(second) => { + let first = std::mem::replace(&mut head, second); + init = f(init, (Position::First, first)); + } + None => return f(init, (Position::Only, head)), + } + } + // Have seen the first item, and there's something left. + init = self.peekable.fold(init, |acc, mut item| { + std::mem::swap(&mut head, &mut item); + f(acc, (Position::Middle, item)) + }); + // The "head" is now the last item. + init = f(init, (Position::Last, head)); + } + init + } } impl ExactSizeIterator for WithPosition where I: ExactSizeIterator {}