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 if it.peek().is_none() {
26 return None;
27 }
28
29 while let Some(next) = it.next() {
30 items.push(next);
31
32 if items.len() == max.get() {
34 break;
35 }
36 }
37 let remaining = it.count();
39 items.shrink_to_fit();
40 Some((items, remaining))
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_it_split() {
49 let a: &[&str] = &[];
50 for v in [0, 1, 5] {
51 let (first, rest) = iterator_split(a.iter(), v);
52 assert_eq!(first.count(), 0);
53 assert_eq!(rest.count(), 0);
54 }
55 let a = &["foo"];
56 for v in [1, 5] {
57 let (first, rest) = iterator_split(a.iter(), v);
58 assert_eq!(first.count(), 1);
59 assert_eq!(rest.count(), 0);
60 }
61 let (first, rest) = iterator_split(a.iter(), 1);
62 assert_eq!(first.count(), 1);
63 assert_eq!(rest.count(), 0);
64 let a = &["foo", "bar", "baz", "blah", "other"];
65 let (first, rest) = iterator_split(a.iter(), 2);
66 assert_eq!(first.count(), 2);
67 assert_eq!(rest.count(), 3);
68 }
69
70 #[test]
71 fn test_split_empty_iterator() {
72 let a: &[&str] = &[];
73 for v in [1, 5].into_iter().map(|v| NonZeroUsize::new(v).unwrap()) {
74 assert!(collect_until(a.iter(), v).is_none());
75 }
76 }
77
78 #[test]
79 fn test_split_nonempty_iterator() {
80 let a = &["foo"];
81
82 let Some((elts, 0)) = collect_until(a.iter(), NonZeroUsize::new(1).unwrap()) else {
83 panic!()
84 };
85 assert_eq!(elts.len(), 1);
86
87 let Some((elts, 0)) = collect_until(a.iter(), const { NonZeroUsize::new(5).unwrap() })
88 else {
89 panic!()
90 };
91 assert_eq!(elts.len(), 1);
92
93 let a = &["foo", "bar", "baz", "blah", "other"];
94 let Some((elts, 3)) = collect_until(a.iter(), const { NonZeroUsize::new(2).unwrap() })
95 else {
96 panic!()
97 };
98 assert_eq!(elts.len(), 2);
99 }
100}