From ad4134540544fe94a0bbd42d4a2d3480ef345ffd Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 21 Mar 2024 18:47:43 -0700 Subject: [PATCH] Make ChunkBy compatible with MSRV --- src/slice/chunk_by.rs | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/slice/chunk_by.rs b/src/slice/chunk_by.rs index 6fb318b04..23bb40363 100644 --- a/src/slice/chunk_by.rs +++ b/src/slice/chunk_by.rs @@ -2,6 +2,15 @@ use crate::iter::plumbing::*; use crate::iter::*; use std::fmt; +fn find_first_index(xs: &[T], pred: &P) -> Option +where + P: Fn(&T, &T) -> bool, +{ + xs.windows(2) + .position(|w| !pred(&w[0], &w[1])) + .map(|i| i + 1) +} + fn find_index(xs: &[T], pred: &P) -> Option where P: Fn(&T, &T) -> bool, @@ -52,11 +61,23 @@ where } } - fn fold_with(self, folder: F) -> F + fn fold_with(mut self, folder: F) -> F where F: Folder, { - folder.consume_iter(self.slice.chunk_by(self.pred)) + // TODO (MSRV 1.77): + // folder.consume_iter(self.slice.chunk_by(self.pred)) + + folder.consume_iter(std::iter::from_fn(move || { + if self.slice.is_empty() { + None + } else { + let i = find_first_index(self.slice, self.pred).unwrap_or(self.slice.len()); + let (head, tail) = self.slice.split_at(i); + self.slice = tail; + Some(head) + } + })) } } @@ -147,11 +168,23 @@ where } } - fn fold_with(self, folder: F) -> F + fn fold_with(mut self, folder: F) -> F where F: Folder, { - folder.consume_iter(self.slice.chunk_by_mut(self.pred)) + // TODO (MSRV 1.77): + // folder.consume_iter(self.slice.chunk_by_mut(self.pred)) + + folder.consume_iter(std::iter::from_fn(move || { + if self.slice.is_empty() { + None + } else { + let i = find_first_index(self.slice, self.pred).unwrap_or(self.slice.len()); + let (head, tail) = std::mem::take(&mut self.slice).split_at_mut(i); + self.slice = tail; + Some(head) + } + })) } }