1use std::cmp::min;
100use std::mem;
101
102pub struct ArbitraryChunkMut<'a, 'b, T: 'a> {
103    data: &'a mut [T],
104    counts: &'b [usize],
105    cursor: usize,
106}
107
108impl<'a, 'b, T> Iterator for ArbitraryChunkMut<'a, 'b, T> {
109    type Item = &'a mut [T];
110
111    fn next(&mut self) -> Option<Self::Item> {
112        if self.cursor > self.counts.len() - 1 {
113            return None;
114        }
115
116        let c = self.counts[self.cursor];
117        self.cursor += 1;
118
119        if c == 0 {
120            return Some(&mut []);
121        }
122
123        if self.data.is_empty() {
124            return None;
125        }
126
127        let point = min(c, self.data.len());
128        let slice = mem::take(&mut self.data);
129        let (l, r) = slice.split_at_mut(point);
130        self.data = r;
131
132        Some(l)
133    }
134
135    fn size_hint(&self) -> (usize, Option<usize>) {
136        let remaining = self.counts.len() - self.cursor;
137        (remaining, Some(remaining))
138    }
139}
140
141pub struct ArbitraryChunk<'a, 'b, T: 'a> {
142    data: &'a [T],
143    counts: &'b [usize],
144    cursor: usize,
145}
146
147impl<'a, 'b, T> Iterator for ArbitraryChunk<'a, 'b, T> {
148    type Item = &'a [T];
149
150    fn next(&mut self) -> Option<Self::Item> {
151        if self.cursor > self.counts.len() - 1 {
152            return None;
153        }
154
155        let c = self.counts[self.cursor];
156        self.cursor += 1;
157
158        if c == 0 {
159            return Some(&[]);
160        }
161
162        if self.data.is_empty() {
163            return None;
164        }
165
166        let point = min(c, self.data.len());
167        let slice = mem::take(&mut self.data);
168        let (l, r) = slice.split_at(point);
169        self.data = r;
170
171        Some(l)
172    }
173
174    fn size_hint(&self) -> (usize, Option<usize>) {
175        let remaining = self.counts.len() - self.cursor;
176        (remaining, Some(remaining))
177    }
178}
179
180pub struct ArbitraryChunkExactMut<'a, 'b, T: 'a> {
181    data: &'a mut [T],
182    counts: &'b [usize],
183    cursor: usize,
184}
185
186impl<'a, 'b, T> Iterator for ArbitraryChunkExactMut<'a, 'b, T> {
187    type Item = &'a mut [T];
188
189    fn next(&mut self) -> Option<Self::Item> {
190        if self.cursor > self.counts.len() - 1 {
191            return None;
192        }
193
194        let c = self.counts[self.cursor];
195        self.cursor += 1;
196
197        if c == 0 {
198            return Some(&mut []);
199        }
200
201        if self.data.is_empty() || c > self.data.len() {
202            return None;
203        }
204
205        let slice = mem::take(&mut self.data);
206        let (l, r) = slice.split_at_mut(c);
207        self.data = r;
208
209        Some(l)
210    }
211
212    fn size_hint(&self) -> (usize, Option<usize>) {
213        let remaining = self.counts.len() - self.cursor;
214        (remaining, Some(remaining))
215    }
216}
217
218impl<'a, 'b, T> ArbitraryChunkExactMut<'a, 'b, T> {
219    pub fn remainder(&'a mut self) -> &'a mut [T] {
220        self.data
221    }
222}
223
224pub struct ArbitraryChunkExact<'a, 'b, T: 'a> {
225    data: &'a [T],
226    counts: &'b [usize],
227    cursor: usize,
228}
229
230impl<'a, 'b, T> Iterator for ArbitraryChunkExact<'a, 'b, T> {
231    type Item = &'a [T];
232
233    fn next(&mut self) -> Option<Self::Item> {
234        if self.cursor > self.counts.len() - 1 {
235            return None;
236        }
237
238        let c = self.counts[self.cursor];
239        self.cursor += 1;
240
241        if c == 0 {
242            return Some(&[]);
243        }
244
245        if self.data.is_empty() || c > self.data.len() {
246            return None;
247        }
248
249        let slice = mem::take(&mut self.data);
250        let (l, r) = slice.split_at(c);
251        self.data = r;
252
253        Some(l)
254    }
255
256    fn size_hint(&self) -> (usize, Option<usize>) {
257        let remaining = self.counts.len() - self.cursor;
258        (remaining, Some(remaining))
259    }
260}
261
262impl<'a, 'b, T> ArbitraryChunkExact<'a, 'b, T> {
263    pub fn remainder(&'a self) -> &'a [T] {
264        self.data
265    }
266}
267
268pub trait ArbitraryChunks<'a, 'b, T> {
269    fn arbitrary_chunks(&'a self, counts: &'b [usize]) -> ArbitraryChunk<'a, 'b, T>;
287
288    fn arbitrary_chunks_mut(&'a mut self, counts: &'b [usize]) -> ArbitraryChunkMut<'a, 'b, T>;
305
306    fn arbitrary_chunks_exact(&'a self, counts: &'b [usize]) -> ArbitraryChunkExact<'a, 'b, T>;
322
323    fn arbitrary_chunks_exact_mut(&'a mut self, counts: &'b [usize]) -> ArbitraryChunkExactMut<'a, 'b, T>;
339}
340
341impl<'a, 'b, T> ArbitraryChunks<'a, 'b, T> for [T] {
342    fn arbitrary_chunks(&'a self, counts: &'b [usize]) -> ArbitraryChunk<'a, 'b, T> {
343        ArbitraryChunk {
344            data: self,
345            counts,
346            cursor: 0,
347        }
348    }
349
350    fn arbitrary_chunks_mut(&'a mut self, counts: &'b [usize]) -> ArbitraryChunkMut<'a, 'b, T> {
351        ArbitraryChunkMut {
352            data: self,
353            counts,
354            cursor: 0,
355        }
356    }
357
358    fn arbitrary_chunks_exact(&'a self, counts: &'b [usize]) -> ArbitraryChunkExact<'a, 'b, T> {
359        ArbitraryChunkExact {
360            data: self,
361            counts,
362            cursor: 0,
363        }
364    }
365
366    fn arbitrary_chunks_exact_mut(&'a mut self, counts: &'b [usize]) -> ArbitraryChunkExactMut<'a, 'b, T> {
367        ArbitraryChunkExactMut {
368            data: self,
369            counts,
370            cursor: 0,
371        }
372    }
373}
374
375#[cfg(test)]
376mod tests {
377    use crate::ArbitraryChunks;
378
379    #[test]
380    fn it_stops_when_chunks_run_out() {
381        let chunks: Vec<usize> = vec![0, 1, 2, 3];
382        let data = vec![8, 7, 6, 5, 4, 3, 2, 1];
383        let chunk_data: Vec<Vec<i32>> = data
384            .arbitrary_chunks(&chunks)
385            .map(|chunk| chunk.to_vec())
386            .collect();
387
388        assert_eq!(Vec::<i32>::new(), chunk_data[0]);
389        assert_eq!(vec![8], chunk_data[1]);
390        assert_eq!(vec![7, 6], chunk_data[2]);
391        assert_eq!(vec![5, 4, 3], chunk_data[3]);
392        assert_eq!(None, chunk_data.get(4));
393    }
394
395    #[test]
396    fn mut_stops_when_chunks_run_out() {
397        let chunks: Vec<usize> = vec![0, 1, 2, 3];
398        let mut data = vec![8, 7, 6, 5, 4, 3, 2, 1];
399        let chunk_data: Vec<Vec<i32>> = data
400            .arbitrary_chunks_mut(&chunks)
401            .map(|chunk| chunk.to_vec())
402            .collect();
403
404        assert_eq!(Vec::<i32>::new(), chunk_data[0]);
405        assert_eq!(vec![8], chunk_data[1]);
406        assert_eq!(vec![7, 6], chunk_data[2]);
407        assert_eq!(vec![5, 4, 3], chunk_data[3]);
408        assert_eq!(None, chunk_data.get(4));
409    }
410
411    #[test]
412    fn exact_stops_when_chunks_run_out() {
413        let chunks: Vec<usize> = vec![0, 1, 2, 3];
414        let data = vec![8, 7, 6, 5, 4, 3, 2, 1];
415        let mut iter = data.arbitrary_chunks_exact(&chunks);
416
417        assert_eq!(&[0i32; 0], iter.next().unwrap());
418        assert_eq!(&[8i32], iter.next().unwrap());
419        assert_eq!(&[7i32, 6], iter.next().unwrap());
420        assert_eq!(&[5i32, 4, 3], iter.next().unwrap());
421        assert_eq!(None, iter.next());
422        assert_eq!(&[2i32, 1], iter.remainder());
423    }
424
425    #[test]
426    fn exact_mut_stops_when_chunks_run_out() {
427        let chunks: Vec<usize> = vec![0, 1, 2, 3];
428        let mut data = vec![8, 7, 6, 5, 4, 3, 2, 1];
429        let mut iter = data.arbitrary_chunks_exact_mut(&chunks);
430
431        assert_eq!(&mut [0i32; 0], iter.next().unwrap());
432        assert_eq!(&mut [8i32], iter.next().unwrap());
433        assert_eq!(&mut [7i32, 6], iter.next().unwrap());
434        assert_eq!(&mut [5i32, 4, 3], iter.next().unwrap());
435        assert_eq!(None, iter.next());
436        assert_eq!(&mut [2i32, 1], iter.remainder());
437    }
438
439    #[test]
440    fn it_accounts_for_trailing_zeros() {
441        let chunks: Vec<usize> = vec![0, 1, 2, 3, 0, 0];
442        let data = vec![8, 7, 6, 5, 4, 3, 2, 1];
443        let chunk_data: Vec<Vec<i32>> = data
444            .arbitrary_chunks(&chunks)
445            .map(|chunk| chunk.to_vec())
446            .collect();
447
448        assert_eq!(Vec::<i32>::new(), chunk_data[0]);
449        assert_eq!(vec![8], chunk_data[1]);
450        assert_eq!(vec![7, 6], chunk_data[2]);
451        assert_eq!(vec![5, 4, 3], chunk_data[3]);
452        assert_eq!(Vec::<i32>::new(), chunk_data[4]);
453        assert_eq!(Vec::<i32>::new(), chunk_data[5]);
454        assert_eq!(None, chunk_data.get(6));
455    }
456
457    #[test]
458    fn mut_accounts_for_trailing_zeros() {
459        let chunks: Vec<usize> = vec![0, 1, 2, 3, 0, 0];
460        let mut data = vec![8, 7, 6, 5, 4, 3, 2, 1];
461        let chunk_data: Vec<Vec<i32>> = data
462            .arbitrary_chunks_mut(&chunks)
463            .map(|chunk| chunk.to_vec())
464            .collect();
465
466        assert_eq!(Vec::<i32>::new(), chunk_data[0]);
467        assert_eq!(vec![8], chunk_data[1]);
468        assert_eq!(vec![7, 6], chunk_data[2]);
469        assert_eq!(vec![5, 4, 3], chunk_data[3]);
470        assert_eq!(Vec::<i32>::new(), chunk_data[4]);
471        assert_eq!(Vec::<i32>::new(), chunk_data[5]);
472        assert_eq!(None, chunk_data.get(6));
473    }
474
475    #[test]
476    fn exact_accounts_for_trailing_zeros() {
477        let chunks: Vec<usize> = vec![0, 1, 2, 3, 0, 0];
478        let data = vec![8, 7, 6, 5, 4, 3, 2, 1];
479        let mut iter = data.arbitrary_chunks_exact(&chunks);
480
481        assert_eq!(&[0i32; 0], iter.next().unwrap());
482        assert_eq!(&[8i32], iter.next().unwrap());
483        assert_eq!(&[7i32, 6], iter.next().unwrap());
484        assert_eq!(&[5i32, 4, 3], iter.next().unwrap());
485        assert_eq!(&[0i32; 0], iter.next().unwrap());
486        assert_eq!(&[0i32; 0], iter.next().unwrap());
487        assert_eq!(None, iter.next());
488        assert_eq!(&[2i32, 1], iter.remainder());
489    }
490
491    #[test]
492    fn exact_mut_accounts_for_trailing_zeros() {
493        let chunks: Vec<usize> = vec![0, 1, 2, 3, 0, 0];
494        let mut data = vec![8, 7, 6, 5, 4, 3, 2, 1];
495        let mut iter = data.arbitrary_chunks_exact_mut(&chunks);
496
497        assert_eq!(&mut [0i32; 0], iter.next().unwrap());
498        assert_eq!(&mut [8i32], iter.next().unwrap());
499        assert_eq!(&mut [7i32, 6], iter.next().unwrap());
500        assert_eq!(&mut [5i32, 4, 3], iter.next().unwrap());
501        assert_eq!(&[0i32; 0], iter.next().unwrap());
502        assert_eq!(&[0i32; 0], iter.next().unwrap());
503        assert_eq!(None, iter.next());
504        assert_eq!(&mut [2i32, 1], iter.remainder());
505    }
506
507    #[test]
508    fn it_stops_when_data_runs_out() {
509        let chunks: Vec<usize> = vec![0, 1, 2, 3];
510        let data = vec![8, 7, 6, 5, 4];
511
512        let chunk_data: Vec<Vec<i32>> = data
513            .arbitrary_chunks(&chunks)
514            .map(|chunk| chunk.to_vec())
515            .collect();
516
517        assert_eq!(Vec::<i32>::new(), chunk_data[0]);
518        assert_eq!(vec![8], chunk_data[1]);
519        assert_eq!(vec![7, 6], chunk_data[2]);
520        assert_eq!(vec![5, 4], chunk_data[3]);
521        assert_eq!(None, chunk_data.get(4));
522    }
523
524    #[test]
525    fn mut_stops_when_data_runs_out() {
526        let chunks: Vec<usize> = vec![0, 1, 2, 3];
527        let mut data = vec![8, 7, 6, 5, 4];
528        let chunk_data: Vec<Vec<i32>> = data
529            .arbitrary_chunks_mut(&chunks)
530            .map(|chunk| chunk.to_vec())
531            .collect();
532
533        assert_eq!(Vec::<i32>::new(), chunk_data[0]);
534        assert_eq!(vec![8], chunk_data[1]);
535        assert_eq!(vec![7, 6], chunk_data[2]);
536        assert_eq!(vec![5, 4], chunk_data[3]);
537        assert_eq!(None, chunk_data.get(4));
538    }
539
540    #[test]
541    fn exact_stops_when_data_runs_out() {
542        let chunks: Vec<usize> = vec![0, 1, 2, 3];
543        let data = vec![8, 7, 6, 5, 4];
544        let mut iter = data.arbitrary_chunks_exact(&chunks);
545
546        assert_eq!(&[0i32; 0], iter.next().unwrap());
547        assert_eq!(&[8i32], iter.next().unwrap());
548        assert_eq!(&[7i32, 6], iter.next().unwrap());
549        assert_eq!(None, iter.next());
550        assert_eq!(&[5i32, 4], iter.remainder());
551    }
552
553    #[test]
554    fn exact_mut_stops_when_data_runs_out() {
555        let chunks: Vec<usize> = vec![0, 1, 2, 3];
556        let mut data = vec![8, 7, 6, 5, 4];
557        let mut iter = data.arbitrary_chunks_exact_mut(&chunks);
558
559        assert_eq!(&mut [0i32; 0], iter.next().unwrap());
560        assert_eq!(&mut [8i32], iter.next().unwrap());
561        assert_eq!(&mut [7i32, 6], iter.next().unwrap());
562        assert_eq!(None, iter.next());
563        assert_eq!(&mut [5i32, 4], iter.remainder());
564    }
565}