diff --git a/tabled/src/iter/layout_iterator.rs b/tabled/src/iter/layout_iterator.rs new file mode 100644 index 00000000..4c491a90 --- /dev/null +++ b/tabled/src/iter/layout_iterator.rs @@ -0,0 +1,77 @@ +#[cfg(feature = "std")] +use crate::{Table, Tabled}; + +/// [`LayoutIterator`] is a convient abstraction to iterate over rows/columns. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct LayoutIterator { + from: usize, + to: usize, + batch: usize, + i: usize, +} + +impl LayoutIterator { + /// Creates a custom [`LayoutIterator`] instance. + pub fn new(from: usize, to: usize, batch: usize) -> Self { + Self { + from, + to, + batch, + i: 0, + } + } + + /// Creates a record iterator for KV table created by [`Table::kv`]. + /// So it basically skips all rows until next record starts. + #[cfg(feature = "std")] + pub fn kv_batches(t: &Table) -> Self + where + T: Tabled, + { + Self::new(0, t.count_rows(), T::LENGTH) + } +} + +impl Iterator for LayoutIterator { + type Item = usize; + + fn next(&mut self) -> Option { + if self.batch == 0 { + return None; + } + + if self.from >= self.to { + return None; + } + + let value = self.i * self.batch; + self.from += self.batch; + self.i += 1; + + Some(value) + } +} + +#[cfg(test)] +mod tests { + use crate::iter::LayoutIterator; + + #[test] + fn test_layout_iterator() { + assert_eq!( + LayoutIterator::new(0, 5, 1).collect::>(), + vec![0, 1, 2, 3, 4] + ); + assert_eq!( + LayoutIterator::new(0, 5, 2).collect::>(), + vec![0, 2, 4] + ); + assert_eq!( + LayoutIterator::new(0, 6, 2).collect::>(), + vec![0, 2, 4] + ); + assert_eq!(LayoutIterator::new(0, 0, 2).collect::>(), vec![]); + assert_eq!(LayoutIterator::new(0, 5, 0).collect::>(), vec![]); + assert_eq!(LayoutIterator::new(0, 0, 0).collect::>(), vec![]); + } +} diff --git a/tabled/src/iter/mod.rs b/tabled/src/iter/mod.rs new file mode 100644 index 00000000..12567832 --- /dev/null +++ b/tabled/src/iter/mod.rs @@ -0,0 +1,5 @@ +//! A module for iterator structures. + +mod layout_iterator; + +pub use layout_iterator::LayoutIterator; diff --git a/tabled/src/lib.rs b/tabled/src/lib.rs index 5468206c..36c79ac5 100644 --- a/tabled/src/lib.rs +++ b/tabled/src/lib.rs @@ -289,6 +289,7 @@ mod tabled; #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub mod builder; pub mod grid; +pub mod iter; pub mod settings; pub mod tables; diff --git a/tabled/tests/core/iter_test.rs b/tabled/tests/core/iter_test.rs new file mode 100644 index 00000000..88c7726b --- /dev/null +++ b/tabled/tests/core/iter_test.rs @@ -0,0 +1,56 @@ +#![cfg(all(feature = "std", feature = "derive"))] + +use tabled::{ + iter::LayoutIterator, + settings::{style::BorderSpanCorrection, Span, Style}, + Table, Tabled, +}; + +use testing_table::test_table; + +test_table!( + push_record, + { + #[derive(Tabled)] + struct Company<'a> { + name: &'a str, + street: &'a str, + city: &'a str, + zip_code: &'a str, + } + + + let companies = vec![ + Company { name: "INTEL CORP", city: "SANTA CLARA", street: "2200 MISSION COLLEGE BLVD, RNB-4-151", zip_code: "95054" }, + Company { name: "Apple Inc.", city: "CUPERTINO", street: "ONE APPLE PARK WAY", zip_code: "95014" }, + ]; + + let mut table = Table::kv(&companies); + + for row in LayoutIterator::kv_batches::(&table) { + table.modify((row, 1), Span::column(-1)); + } + + table.with(Style::modern()); + table.with(BorderSpanCorrection); + + table + }, + "┌─────────────────────────────────────────────────┐" + "│ INTEL CORP │" + "├──────────┬──────────────────────────────────────┤" + "│ street │ 2200 MISSION COLLEGE BLVD, RNB-4-151 │" + "├──────────┼──────────────────────────────────────┤" + "│ city │ SANTA CLARA │" + "├──────────┼──────────────────────────────────────┤" + "│ zip_code │ 95054 │" + "├──────────┴──────────────────────────────────────┤" + "│ Apple Inc. │" + "├──────────┬──────────────────────────────────────┤" + "│ street │ ONE APPLE PARK WAY │" + "├──────────┼──────────────────────────────────────┤" + "│ city │ CUPERTINO │" + "├──────────┼──────────────────────────────────────┤" + "│ zip_code │ 95014 │" + "└──────────┴──────────────────────────────────────┘" +); diff --git a/tabled/tests/core/mod.rs b/tabled/tests/core/mod.rs index 4c6f90fc..ffd373bf 100644 --- a/tabled/tests/core/mod.rs +++ b/tabled/tests/core/mod.rs @@ -3,6 +3,7 @@ mod compact_table; mod extended_table_test; mod index_test; mod iter_table; +mod iter_test; mod kv_test; mod pool_table; mod table_test;