Skip to content

Commit c417ae0

Browse files
committed
simplify the min_columns calculation and add edge cases tests
1 parent 2aa401b commit c417ae0

File tree

2 files changed

+53
-15
lines changed

2 files changed

+53
-15
lines changed

src/lib.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -196,30 +196,34 @@ impl<T: AsRef<str>> Grid<T> {
196196
};
197197
}
198198

199-
// Calculate number of columns with widest column size.
200-
let max_num_columns = self.options.width / widest_column;
201-
202-
// Caculate approximate number of lines and columns.
203-
let appr_num_lines = div_ceil(self.cells.len(), max_num_columns);
204-
let appr_num_columns = div_ceil(self.cells.len(), appr_num_lines);
199+
// Calculate minimum number of columns with the widest column size.
200+
let min_columns = self
201+
.cells
202+
.len()
203+
.min((self.options.width + self.options.filling.width()) / widest_column);
204+
// Caculate approximate number of rows and columns.
205+
let min_lines = div_ceil(self.cells.len(), min_columns);
206+
// let appr_num_columns = div_ceil(self.cells.len(), appr_num_lines);
205207

206208
// This is a potential dimension, which can definitely fit all of the cells.
207-
let mut potential_dimension = self.compute_dimensions(appr_num_lines, appr_num_columns);
209+
let mut potential_dimension = self.compute_dimensions(min_lines, min_columns);
208210
// If all of the cells can be fit on one line, return.
209-
if appr_num_lines == 1 {
211+
if min_lines == 1 {
210212
return potential_dimension;
211213
}
212214

213215
// Try to increase number of columns, to see if new dimension can still fit.
214-
for num_columns in appr_num_columns + 1.. {
215-
let new_width = self.options.width - (num_columns - 1) * self.options.filling.width();
216-
let num_lines = div_ceil(self.cells.len(), num_columns);
217-
let new_dimension = self.compute_dimensions(num_lines, num_columns);
218-
if new_dimension.widths.iter().sum::<usize>() <= new_width {
219-
potential_dimension = new_dimension;
220-
} else {
216+
for num_columns in min_columns + 1.. {
217+
let new_width = (num_columns - 1) * self.options.filling.width();
218+
if new_width > self.options.width {
221219
break;
222220
}
221+
222+
let num_rows = div_ceil(self.cells.len(), num_columns);
223+
let new_dimension = self.compute_dimensions(num_rows, num_columns);
224+
if new_dimension.widths.iter().sum::<usize>() <= self.options.width - new_width {
225+
potential_dimension = new_dimension;
226+
}
223227
}
224228

225229
potential_dimension

tests/test.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,40 @@ fn use_max_possible_width() {
345345
assert_eq!(grid.row_count(), 2);
346346
}
347347

348+
#[test]
349+
fn use_minimal_optimal_lines() {
350+
let grid = Grid::new(
351+
vec!["a", "b", "ccc", "ddd"],
352+
GridOptions {
353+
direction: Direction::TopToBottom,
354+
filling: Filling::Spaces(2),
355+
width: 6,
356+
},
357+
);
358+
359+
let expected = "a ccc\nb ddd\n";
360+
assert_eq!(grid.to_string(), expected);
361+
}
362+
363+
#[test]
364+
fn weird_column_edge_case() {
365+
let grid = Grid::new(
366+
vec!["0", "1", "222222222", "333333333", "4", "5", "6", "7", "8"],
367+
GridOptions {
368+
direction: Direction::TopToBottom,
369+
filling: Filling::Spaces(2),
370+
width: 21,
371+
},
372+
);
373+
374+
let expected = "\
375+
0 222222222 4 6 8\n\
376+
1 333333333 5 7\n\
377+
";
378+
379+
assert_eq!(grid.to_string(), expected);
380+
}
381+
348382
// These test are based on the tests in uutils ls, to ensure we won't break
349383
// it while editing this library.
350384
mod uutils_ls {

0 commit comments

Comments
 (0)