matrix_sdk_ffi/
chunk_iterator.rs
1use std::{cmp, mem, sync::RwLock};
7
8pub struct ChunkIterator<T> {
9 items: RwLock<Vec<T>>,
10}
11
12impl<T> ChunkIterator<T> {
13 pub fn new(items: Vec<T>) -> Self {
14 Self { items: RwLock::new(items) }
15 }
16
17 pub fn len(&self) -> u32 {
18 self.items.read().unwrap().len().try_into().unwrap()
19 }
20
21 pub fn next(&self, chunk_size: u32) -> Option<Vec<T>> {
22 if self.items.read().unwrap().is_empty() {
23 None
24 } else if chunk_size == 0 {
25 Some(Vec::new())
26 } else {
27 let mut items = self.items.write().unwrap();
28
29 let chunk_size = cmp::min(items.len(), chunk_size.try_into().unwrap());
31 let mut tail = items.split_off(chunk_size);
33 mem::swap(&mut tail, &mut items);
36 let head = tail;
38
39 Some(head)
40 }
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::ChunkIterator;
47
48 #[test]
49 fn test_len() {
50 assert_eq!(ChunkIterator::<u8>::new(vec![1, 2, 3]).len(), 3);
51 assert_eq!(ChunkIterator::<u8>::new(vec![]).len(), 0);
52 }
53
54 #[test]
55 fn test_next() {
56 let iterator = ChunkIterator::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
57
58 assert_eq!(iterator.next(3), Some(vec![1, 2, 3]));
59 assert_eq!(iterator.next(5), Some(vec![4, 5, 6, 7, 8]));
60 assert_eq!(iterator.next(0), Some(vec![]));
61 assert_eq!(iterator.next(1), Some(vec![9]));
62 assert_eq!(iterator.next(3), Some(vec![10, 11]));
63 assert_eq!(iterator.next(2), None);
64 assert_eq!(iterator.next(2), None);
65 }
66}