tabled/iter/
layout_iterator.rs

1#[cfg(feature = "std")]
2use crate::{Table, Tabled};
3
4/// [`LayoutIterator`] is a convient abstraction to iterate over rows/columns.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
6pub struct LayoutIterator {
7    from: usize,
8    to: usize,
9    batch: usize,
10    i: usize,
11}
12
13impl LayoutIterator {
14    /// Creates a custom [`LayoutIterator`] instance.
15    pub fn new(from: usize, to: usize, batch: usize) -> Self {
16        Self {
17            from,
18            to,
19            batch,
20            i: 0,
21        }
22    }
23
24    /// Creates a record iterator for KV table created by [`Table::kv`].
25    /// So it basically skips all rows until next record starts.
26    #[cfg(feature = "std")]
27    pub fn kv_batches<T>(t: &Table) -> Self
28    where
29        T: Tabled,
30    {
31        Self::new(0, t.count_rows(), T::LENGTH)
32    }
33}
34
35impl Iterator for LayoutIterator {
36    type Item = usize;
37
38    fn next(&mut self) -> Option<Self::Item> {
39        if self.batch == 0 {
40            return None;
41        }
42
43        if self.from >= self.to {
44            return None;
45        }
46
47        let value = self.i * self.batch;
48        self.from += self.batch;
49        self.i += 1;
50
51        Some(value)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use crate::iter::LayoutIterator;
58
59    #[test]
60    fn test_layout_iterator() {
61        assert_eq!(
62            LayoutIterator::new(0, 5, 1).collect::<Vec<_>>(),
63            vec![0, 1, 2, 3, 4]
64        );
65        assert_eq!(
66            LayoutIterator::new(0, 5, 2).collect::<Vec<_>>(),
67            vec![0, 2, 4]
68        );
69        assert_eq!(
70            LayoutIterator::new(0, 6, 2).collect::<Vec<_>>(),
71            vec![0, 2, 4]
72        );
73        assert_eq!(LayoutIterator::new(0, 0, 2).collect::<Vec<_>>(), vec![]);
74        assert_eq!(LayoutIterator::new(0, 5, 0).collect::<Vec<_>>(), vec![]);
75        assert_eq!(LayoutIterator::new(0, 0, 0).collect::<Vec<_>>(), vec![]);
76    }
77}