@@ -6,3 +6,97 @@ mod command;
6
6
mod tracing_util;
7
7
pub use command:: * ;
8
8
pub use tracing_util:: * ;
9
+
10
+ /// Given an iterator that's clonable, split it into two iterators
11
+ /// at a given maximum number of elements.
12
+ pub fn iterator_split < I > (
13
+ it : I ,
14
+ max : usize ,
15
+ ) -> ( impl Iterator < Item = I :: Item > , impl Iterator < Item = I :: Item > )
16
+ where
17
+ I : Iterator + Clone ,
18
+ {
19
+ let rest = it. clone ( ) ;
20
+ ( it. take ( max) , rest. skip ( max) )
21
+ }
22
+
23
+ /// Given an iterator that's clonable, split off the first N elements
24
+ /// at the pivot point. If the iterator would be empty, return None.
25
+ /// Return the count of the remainder.
26
+ pub fn iterator_split_nonempty_rest_count < I > (
27
+ it : I ,
28
+ max : usize ,
29
+ ) -> Option < ( impl Iterator < Item = I :: Item > , usize ) >
30
+ where
31
+ I : Iterator + Clone ,
32
+ {
33
+ let rest = it. clone ( ) ;
34
+ let mut it = it. peekable ( ) ;
35
+ if it. peek ( ) . is_some ( ) {
36
+ Some ( ( it. take ( max) , rest. skip ( max) . count ( ) ) )
37
+ } else {
38
+ None
39
+ }
40
+ }
41
+
42
+ #[ cfg( test) ]
43
+ mod 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 [ 0 , 1 , 5 ] {
73
+ assert ! ( iterator_split_nonempty_rest_count( 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, 1 ) ) = iterator_split_nonempty_rest_count ( a. iter ( ) , 0 ) else {
82
+ panic ! ( )
83
+ } ;
84
+ assert_eq ! ( elts. count( ) , 0 ) ;
85
+
86
+ let Some ( ( elts, 0 ) ) = iterator_split_nonempty_rest_count ( a. iter ( ) , 1 ) else {
87
+ panic ! ( )
88
+ } ;
89
+ assert_eq ! ( elts. count( ) , 1 ) ;
90
+
91
+ let Some ( ( elts, 0 ) ) = iterator_split_nonempty_rest_count ( a. iter ( ) , 5 ) else {
92
+ panic ! ( )
93
+ } ;
94
+ assert_eq ! ( elts. count( ) , 1 ) ;
95
+
96
+ let a = & [ "foo" , "bar" , "baz" , "blah" , "other" ] ;
97
+ let Some ( ( elts, 3 ) ) = iterator_split_nonempty_rest_count ( a. iter ( ) , 2 ) else {
98
+ panic ! ( )
99
+ } ;
100
+ assert_eq ! ( elts. count( ) , 2 ) ;
101
+ }
102
+ }
0 commit comments