diff options
Diffstat (limited to 'crates/typst-utils/src')
| -rw-r--r-- | crates/typst-utils/src/lib.rs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/crates/typst-utils/src/lib.rs b/crates/typst-utils/src/lib.rs index f3fe79d2..b59fe2f7 100644 --- a/crates/typst-utils/src/lib.rs +++ b/crates/typst-utils/src/lib.rs @@ -128,6 +128,20 @@ pub trait SliceExt<T> { where F: FnMut(&T) -> K, K: PartialEq; + + /// Computes two indices which split a slice into three parts. + /// + /// - A prefix which matches `f` + /// - An inner portion + /// - A suffix which matches `f` and does not overlap with the prefix + /// + /// If all elements match `f`, the prefix becomes `self` and the suffix + /// will be empty. + /// + /// Returns the indices at which the inner portion and the suffix start. + fn split_prefix_suffix<F>(&self, f: F) -> (usize, usize) + where + F: FnMut(&T) -> bool; } impl<T> SliceExt<T> for [T] { @@ -157,6 +171,19 @@ impl<T> SliceExt<T> for [T] { fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F> { GroupByKey { slice: self, f } } + + fn split_prefix_suffix<F>(&self, mut f: F) -> (usize, usize) + where + F: FnMut(&T) -> bool, + { + let start = self.iter().position(|v| !f(v)).unwrap_or(self.len()); + let end = self + .iter() + .skip(start) + .rposition(|v| !f(v)) + .map_or(start, |i| start + i + 1); + (start, end) + } } /// This struct is created by [`SliceExt::group_by_key`]. |
