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}