Skip to content

Commit 965a800

Browse files
authored
Merge pull request #487 from zhiburt/patch/add-layout-iterator
Add tabled::iter::LayoutIterator
2 parents 7b85b29 + dc3d565 commit 965a800

File tree

5 files changed

+140
-0
lines changed

5 files changed

+140
-0
lines changed

tabled/src/iter/layout_iterator.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#[cfg(feature = "std")]
2+
use 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)]
6+
pub struct LayoutIterator {
7+
from: usize,
8+
to: usize,
9+
batch: usize,
10+
i: usize,
11+
}
12+
13+
impl 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+
35+
impl 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)]
56+
mod 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+
}

tabled/src/iter/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//! A module for iterator structures.
2+
3+
mod layout_iterator;
4+
5+
pub use layout_iterator::LayoutIterator;

tabled/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ mod tabled;
289289
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
290290
pub mod builder;
291291
pub mod grid;
292+
pub mod iter;
292293
pub mod settings;
293294
pub mod tables;
294295

tabled/tests/core/iter_test.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#![cfg(all(feature = "std", feature = "derive"))]
2+
3+
use tabled::{
4+
iter::LayoutIterator,
5+
settings::{style::BorderSpanCorrection, Span, Style},
6+
Table, Tabled,
7+
};
8+
9+
use testing_table::test_table;
10+
11+
test_table!(
12+
push_record,
13+
{
14+
#[derive(Tabled)]
15+
struct Company<'a> {
16+
name: &'a str,
17+
street: &'a str,
18+
city: &'a str,
19+
zip_code: &'a str,
20+
}
21+
22+
23+
let companies = vec![
24+
Company { name: "INTEL CORP", city: "SANTA CLARA", street: "2200 MISSION COLLEGE BLVD, RNB-4-151", zip_code: "95054" },
25+
Company { name: "Apple Inc.", city: "CUPERTINO", street: "ONE APPLE PARK WAY", zip_code: "95014" },
26+
];
27+
28+
let mut table = Table::kv(&companies);
29+
30+
for row in LayoutIterator::kv_batches::<Company>(&table) {
31+
table.modify((row, 1), Span::column(-1));
32+
}
33+
34+
table.with(Style::modern());
35+
table.with(BorderSpanCorrection);
36+
37+
table
38+
},
39+
"┌─────────────────────────────────────────────────┐"
40+
"│ INTEL CORP │"
41+
"├──────────┬──────────────────────────────────────┤"
42+
"│ street │ 2200 MISSION COLLEGE BLVD, RNB-4-151 │"
43+
"├──────────┼──────────────────────────────────────┤"
44+
"│ city │ SANTA CLARA │"
45+
"├──────────┼──────────────────────────────────────┤"
46+
"│ zip_code │ 95054 │"
47+
"├──────────┴──────────────────────────────────────┤"
48+
"│ Apple Inc. │"
49+
"├──────────┬──────────────────────────────────────┤"
50+
"│ street │ ONE APPLE PARK WAY │"
51+
"├──────────┼──────────────────────────────────────┤"
52+
"│ city │ CUPERTINO │"
53+
"├──────────┼──────────────────────────────────────┤"
54+
"│ zip_code │ 95014 │"
55+
"└──────────┴──────────────────────────────────────┘"
56+
);

tabled/tests/core/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod compact_table;
33
mod extended_table_test;
44
mod index_test;
55
mod iter_table;
6+
mod iter_test;
67
mod kv_test;
78
mod pool_table;
89
mod table_test;

0 commit comments

Comments
 (0)