bootc_internal_utils/
iterators.rs1use std::num::NonZeroUsize;
2
3pub fn iterator_split<I>(
6 it: I,
7 max: usize,
8) -> (impl Iterator<Item = I::Item>, impl Iterator<Item = I::Item>)
9where
10 I: Iterator + Clone,
11{
12 let rest = it.clone();
13 (it.take(max), rest.skip(max))
14}
15
16pub fn collect_until<I>(it: I, max: NonZeroUsize) -> Option<(Vec<I::Item>, usize)>
19where
20 I: Iterator,
21{
22 let mut items = Vec::with_capacity(max.get());
23
24 let mut it = it.peekable();
25 let _ = it.peek()?;
27
28 for next in it.by_ref() {
29 items.push(next);
30
31 if items.len() == max.get() {
33 break;
34 }
35 }
36 let remaining = it.count();
38 items.shrink_to_fit();
39 Some((items, remaining))
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn test_it_split() {
48 let a: &[&str] = &[];
49 for v in [0, 1, 5] {
50 let (first, rest) = iterator_split(a.iter(), v);
51 assert_eq!(first.count(), 0);
52 assert_eq!(rest.count(), 0);
53 }
54 let a = &["foo"];
55 for v in [1, 5] {
56 let (first, rest) = iterator_split(a.iter(), v);
57 assert_eq!(first.count(), 1);
58 assert_eq!(rest.count(), 0);
59 }
60 let (first, rest) = iterator_split(a.iter(), 1);
61 assert_eq!(first.count(), 1);
62 assert_eq!(rest.count(), 0);
63 let a = &["foo", "bar", "baz", "blah", "other"];
64 let (first, rest) = iterator_split(a.iter(), 2);
65 assert_eq!(first.count(), 2);
66 assert_eq!(rest.count(), 3);
67 }
68
69 #[test]
70 fn test_split_empty_iterator() {
71 let a: &[&str] = &[];
72 for v in [1, 5].into_iter().map(|v| NonZeroUsize::new(v).unwrap()) {
73 assert!(collect_until(a.iter(), v).is_none());
74 }
75 }
76
77 #[test]
78 fn test_split_nonempty_iterator() {
79 let a = &["foo"];
80
81 let Some((elts, 0)) = collect_until(a.iter(), NonZeroUsize::new(1).unwrap()) else {
82 panic!()
83 };
84 assert_eq!(elts.len(), 1);
85
86 let Some((elts, 0)) = collect_until(a.iter(), const { NonZeroUsize::new(5).unwrap() })
87 else {
88 panic!()
89 };
90 assert_eq!(elts.len(), 1);
91
92 let a = &["foo", "bar", "baz", "blah", "other"];
93 let Some((elts, 3)) = collect_until(a.iter(), const { NonZeroUsize::new(2).unwrap() })
94 else {
95 panic!()
96 };
97 assert_eq!(elts.len(), 2);
98 }
99}