Skip to content

Commit

Permalink
Separate title row from other rows in table
Browse files Browse the repository at this point in the history
  • Loading branch information
devashishdxt committed Dec 10, 2020
1 parent 6f6e345 commit 61a4b6c
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 75 deletions.
41 changes: 38 additions & 3 deletions cli-table/src/row.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::io::Result;

use termcolor::{Buffer, BufferWriter};
use termcolor::{Buffer, BufferWriter, ColorSpec};

use crate::{
buffers::Buffers,
cell::{Cell, CellStruct, Dimension as CellDimension},
table::Dimension as TableDimension,
utils::transpose,
table::{Dimension as TableDimension, TableFormat},
utils::{print_char, print_vertical_line, println_str, transpose},
};

/// Concrete row of a table
Expand All @@ -29,6 +29,41 @@ impl RowStruct {

Dimension { widths, height }
}

pub(crate) fn print_writer(
&self,
writer: &BufferWriter,
dimension: Dimension,
format: &TableFormat,
color_spec: &ColorSpec,
) -> Result<()> {
let buffers = self.buffers(&writer, dimension)?;

for line in buffers.into_iter() {
print_vertical_line(&writer, format.border.left.as_ref(), &color_spec)?;

let mut line_buffers = line.into_iter().peekable();

while let Some(buffer) = line_buffers.next() {
print_char(&writer, ' ', &color_spec)?;
writer.print(&buffer)?;
print_char(&writer, ' ', &color_spec)?;

match line_buffers.peek() {
Some(_) => {
print_vertical_line(&writer, format.separator.column.as_ref(), &color_spec)?
}
None => {
print_vertical_line(&writer, format.border.right.as_ref(), &color_spec)?
}
}
}

println_str(&writer, "", &color_spec)?;
}

Ok(())
}
}

impl Buffers for RowStruct {
Expand Down
112 changes: 47 additions & 65 deletions cli-table/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ use std::io::Result;
use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec};

use crate::{
buffers::Buffers,
row::{Dimension as RowDimension, Row, RowStruct},
style::{Style, StyleStruct},
utils::*,
};

/// Struct for building a table on command line
pub struct TableStruct {
/// Title row of the table
title: Option<RowStruct>,
/// Rows in the table
rows: Vec<RowStruct>,
/// Format of the table
Expand All @@ -22,6 +23,12 @@ pub struct TableStruct {
}

impl TableStruct {
/// Used to add a title row of a table
pub fn title<T: Row>(mut self, title: T) -> Self {
self.title = Some(title.row());
self
}

/// Used to set border of a table
pub fn border(mut self, border: Border) -> Self {
self.format.border = border;
Expand Down Expand Up @@ -59,14 +66,17 @@ impl TableStruct {
return Default::default();
}

let mut heights = Vec::with_capacity(self.rows.len());
let mut heights = Vec::with_capacity(self.rows.len() + 1);

let row_dimension = self.rows[0].required_dimension();
let row_dimension = match self.title {
Some(ref title) => title.required_dimension(),
None => self.rows[0].required_dimension(),
};

let mut widths = row_dimension.widths;
heights.push(row_dimension.height);

for row in self.rows.iter().skip(1) {
for row in self.rows.iter() {
let row_dimension = row.required_dimension();

heights.push(row_dimension.height);
Expand All @@ -84,6 +94,7 @@ impl TableStruct {
fn print_writer(&self, writer: BufferWriter) -> Result<()> {
let table_dimension = self.required_dimension();
let row_dimensions: Vec<RowDimension> = table_dimension.clone().into();
let mut row_dimensions = row_dimensions.into_iter();
let color_spec = self.color_spec();

print_horizontal_line(
Expand All @@ -94,72 +105,42 @@ impl TableStruct {
&color_spec,
)?;

let mut rows = self.rows.iter().zip(row_dimensions.into_iter()).peekable();
if let Some(ref title) = self.title {
let title_dimension = row_dimensions.next().unwrap();
title.print_writer(&writer, title_dimension, &self.format, &color_spec)?;

if self.format.separator.title.is_some() {
print_horizontal_line(
&writer,
self.format.separator.title.as_ref(),
&table_dimension,
&self.format,
&color_spec,
)?
} else {
print_horizontal_line(
&writer,
self.format.separator.row.as_ref(),
&table_dimension,
&self.format,
&color_spec,
)?
}
}

let mut first = true;
let mut rows = self.rows.iter().zip(row_dimensions).peekable();

while let Some((row, row_dimension)) = rows.next() {
let buffers = row.buffers(&writer, row_dimension)?;

for line in buffers.into_iter() {
print_vertical_line(&writer, self.format.border.left.as_ref(), &color_spec)?;

let mut line_buffers = line.into_iter().peekable();

while let Some(buffer) = line_buffers.next() {
print_char(&writer, ' ', &color_spec)?;
writer.print(&buffer)?;
print_char(&writer, ' ', &color_spec)?;

match line_buffers.peek() {
Some(_) => print_vertical_line(
&writer,
self.format.separator.column.as_ref(),
&color_spec,
)?,
None => print_vertical_line(
&writer,
self.format.border.right.as_ref(),
&color_spec,
)?,
}
}

println_str(&writer, "", &color_spec)?;
}
row.print_writer(&writer, row_dimension, &self.format, &color_spec)?;

match rows.peek() {
Some(_) => {
if first {
if self.format.separator.title.is_some() {
print_horizontal_line(
&writer,
self.format.separator.title.as_ref(),
&table_dimension,
&self.format,
&color_spec,
)?
} else {
print_horizontal_line(
&writer,
self.format.separator.row.as_ref(),
&table_dimension,
&self.format,
&color_spec,
)?
}
} else {
print_horizontal_line(
&writer,
self.format.separator.row.as_ref(),
&table_dimension,
&self.format,
&color_spec,
)?
}

first = false;
}
Some(_) => print_horizontal_line(
&writer,
self.format.separator.row.as_ref(),
&table_dimension,
&self.format,
&color_spec,
)?,
None => print_horizontal_line(
&writer,
self.format.border.bottom.as_ref(),
Expand Down Expand Up @@ -189,6 +170,7 @@ where
let rows = self.into_iter().map(Row::row).collect();

TableStruct {
title: Default::default(),
rows,
format: Default::default(),
style: Default::default(),
Expand Down
9 changes: 2 additions & 7 deletions cli-table/src/title.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,8 @@ where
&'a R: Row,
{
fn with_title(self) -> TableStruct {
let mut data: Vec<RowStruct> = self.into_iter().map(|row| row.row()).collect();
let table = self.table();
let title = R::title();

let mut rows = Vec::with_capacity(data.len() + 1);
rows.push(title);
rows.append(&mut data);

rows.table()
table.title(title)
}
}

0 comments on commit 61a4b6c

Please sign in to comment.