Encapsulate table widths

Adding a header row automatically added the widths to the table and returned the row, but adding a file’s row didn’t add the widths. Now they’re consistent.

By having the widths be in a separate type, we can separate the two out later, rather than having one refer to the other.
This commit is contained in:
Benjamin Sago 2017-07-03 17:40:05 +01:00
parent 97236128ea
commit 7b64176929
3 changed files with 37 additions and 15 deletions

View File

@ -147,6 +147,7 @@ impl<'a> Render<'a> {
if self.opts.header { if self.opts.header {
let header = table.header_row(); let header = table.header_row();
table.add_widths(&header);
rows.push(self.render_header(header)); rows.push(self.render_header(header));
} }

View File

@ -86,7 +86,9 @@ impl<'a> Render<'a> {
let mut rows = Vec::new(); let mut rows = Vec::new();
if self.details.header { if self.details.header {
rows.push(drender.render_header(table.header_row())); let row = table.header_row();
table.add_widths(&row);
rows.push(drender.render_header(row));
} }
(table, rows) (table, rows)

View File

@ -1,4 +1,5 @@
use std::cmp::max; use std::cmp::max;
use std::ops::Deref;
use std::sync::{Mutex, MutexGuard}; use std::sync::{Mutex, MutexGuard};
use datetime::TimeZone; use datetime::TimeZone;
@ -75,7 +76,7 @@ pub struct Table<'a> {
columns: &'a [Column], columns: &'a [Column],
colours: &'a Colours, colours: &'a Colours,
env: &'a Environment, env: &'a Environment,
widths: Vec<usize>, widths: TableWidths,
} }
#[derive(Clone)] #[derive(Clone)]
@ -85,7 +86,7 @@ pub struct Row {
impl<'a, 'f> Table<'a> { impl<'a, 'f> Table<'a> {
pub fn new(columns: &'a [Column], colours: &'a Colours, env: &'a Environment) -> Table<'a> { pub fn new(columns: &'a [Column], colours: &'a Colours, env: &'a Environment) -> Table<'a> {
let widths = vec![ 0; columns.len() ]; let widths = TableWidths::zero(columns.len());
Table { columns, colours, env, widths } Table { columns, colours, env, widths }
} }
@ -94,17 +95,13 @@ impl<'a, 'f> Table<'a> {
} }
pub fn widths(&self) -> &[usize] { pub fn widths(&self) -> &[usize] {
&self.widths &*self.widths
} }
pub fn header_row(&mut self) -> Row { pub fn header_row(&self) -> Row {
let mut cells = Vec::with_capacity(self.columns.len()); let cells = self.columns.iter()
.map(|c| TextCell::paint_str(self.colours.header, c.header()))
for (old_width, column) in self.widths.iter_mut().zip(self.columns.iter()) { .collect();
let column = TextCell::paint_str(self.colours.header, column.header());
*old_width = max(*old_width, *column.width);
cells.push(column);
}
Row { cells } Row { cells }
} }
@ -118,9 +115,7 @@ impl<'a, 'f> Table<'a> {
} }
pub fn add_widths(&mut self, row: &Row) { pub fn add_widths(&mut self, row: &Row) {
for (old_width, cell) in self.widths.iter_mut().zip(row.cells.iter()) { self.widths.add_widths(row)
*old_width = max(*old_width, *cell.width);
}
} }
fn permissions_plus(&self, file: &File, xattrs: bool) -> f::PermissionsPlus { fn permissions_plus(&self, file: &File, xattrs: bool) -> f::PermissionsPlus {
@ -167,3 +162,27 @@ impl<'a, 'f> Table<'a> {
cell cell
} }
} }
pub struct TableWidths(Vec<usize>);
impl Deref for TableWidths {
type Target = [usize];
fn deref<'a>(&'a self) -> &'a Self::Target {
&self.0
}
}
impl TableWidths {
pub fn zero(count: usize) -> TableWidths {
TableWidths(vec![ 0; count ])
}
pub fn add_widths(&mut self, row: &Row) {
for (old_width, cell) in self.0.iter_mut().zip(row.cells.iter()) {
*old_width = max(*old_width, *cell.width);
}
}
}