From 4e36ac179fc5341b35221018573e265a1f1a0a53 Mon Sep 17 00:00:00 2001 From: Pierre-Henri Symoneaux Date: Mon, 5 Jun 2017 15:34:54 +0200 Subject: Fixed lint (+clippy) warnings and line endings Added some lint rustc checks and fixed warnings. Fixed some clippy warnings & errors Converted remaining CRLF line endings to LF --- .gitignore | 2 + examples/basic.rs | 34 ++--- examples/slices.rs | 22 +-- examples/style.rs | 16 +- examples/tictactoe.rs | 22 +-- src/cell.rs | 89 ++++++----- src/format.rs | 400 ++++++++++++++++++++++++++------------------------ src/lib.rs | 196 +++++++++++++------------ src/main.rs | 12 +- src/row.rs | 39 ++--- src/utils.rs | 20 +-- 11 files changed, 443 insertions(+), 409 deletions(-) diff --git a/.gitignore b/.gitignore index e9e2199..93ffd2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target/ /Cargo.lock + +\.vscode/ diff --git a/examples/basic.rs b/examples/basic.rs index 4ca5d39..fe397d8 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -4,23 +4,23 @@ use prettytable::Table; use prettytable::row::Row; use prettytable::cell::Cell; -/* - Following main function will print : - +---------+------+---------+ - | ABC | DEFG | HIJKLMN | - +---------+------+---------+ - | foobar | bar | foo | - +---------+------+---------+ - | foobar2 | bar2 | foo2 | - +---------+------+---------+ - Modified : - +---------+------+---------+ - | ABC | DEFG | HIJKLMN | - +---------+------+---------+ - | foobar | bar | foo | - +---------+------+---------+ - | foobar2 | bar2 | new_foo | - +---------+------+---------+ +/* + Following main function will print : + +---------+------+---------+ + | ABC | DEFG | HIJKLMN | + +---------+------+---------+ + | foobar | bar | foo | + +---------+------+---------+ + | foobar2 | bar2 | foo2 | + +---------+------+---------+ + Modified : + +---------+------+---------+ + | ABC | DEFG | HIJKLMN | + +---------+------+---------+ + | foobar | bar | foo | + +---------+------+---------+ + | foobar2 | bar2 | new_foo | + +---------+------+---------+ */ fn main() { let mut table = Table::new(); diff --git a/examples/slices.rs b/examples/slices.rs index 38e07ee..e66ba36 100644 --- a/examples/slices.rs +++ b/examples/slices.rs @@ -11,17 +11,17 @@ fn main() { let slice = slice.slice(2..); let slice = slice.slice(..3); - /* - Will print - +----+----+----+ - | t1 | t2 | t3 | - +====+====+====+ - | 2 | 2 | 2 | - +----+----+----+ - | 3 | 3 | 3 | - +----+----+----+ - | 4 | 4 | 4 | - +----+----+----+ + /* + Will print + +----+----+----+ + | t1 | t2 | t3 | + +====+====+====+ + | 2 | 2 | 2 | + +----+----+----+ + | 3 | 3 | 3 | + +----+----+----+ + | 4 | 4 | 4 | + +----+----+----+ */ slice.printstd(); diff --git a/examples/style.rs b/examples/style.rs index 843061f..d001fca 100644 --- a/examples/style.rs +++ b/examples/style.rs @@ -15,14 +15,14 @@ fn main() { table.add_row(row![FrByb->"ABC", "DEFG", "HIJKLMN"]); // Add style to a full row table.add_row(row![FY => "styled", "bar", "foo"]); - table.add_row(Row::new(vec![ - Cell::new("foobar2"), - // Create a cell with a red foreground color - Cell::new("bar2").with_style(Attr::ForegroundColor(color::RED)), - // Create a cell with red foreground color, yellow background color, with bold characters - Cell::new("foo2").style_spec("FrByb"), - // Using the cell! macro - cell!(Fr->"red")]) + table.add_row(Row::new(vec![ + Cell::new("foobar2"), + // Create a cell with a red foreground color + Cell::new("bar2").with_style(Attr::ForegroundColor(color::RED)), + // Create a cell with red foreground color, yellow background color, with bold characters + Cell::new("foo2").style_spec("FrByb"), + // Using the cell! macro + cell!(Fr->"red")]) ); table.printstd(); diff --git a/examples/tictactoe.rs b/examples/tictactoe.rs index 49444eb..c8ffdc5 100644 --- a/examples/tictactoe.rs +++ b/examples/tictactoe.rs @@ -23,12 +23,12 @@ fn main() { print!("{} plays > ", current); stdout.flush().unwrap(); stdin.read_line(&mut line).expect("Cannot read input"); - let i = match usize::from_str(line.trim()) { - Ok(i) => i, + let i = match usize::from_str(line.trim()) { + Ok(i) => i, _ => { println!("Bad input"); continue; - } + } }; if i < 1 || i > 9 { println!("Bad input, should be between 1 and 9"); @@ -57,14 +57,14 @@ fn main() { } fn get(table: &Table, x: usize, y: usize) -> String { - match table.get_row(y) { - Some(ref r) => { - match r.get_cell(x) { - Some(ref c) => c.to_string(), - _ => EMPTY.to_string(), + match table.get_row(y) { + Some(r) => { + match r.get_cell(x) { + Some(c) => c.to_string(), + _ => EMPTY.to_string(), } - } - _ => EMPTY.to_string(), + } + _ => EMPTY.to_string(), } } @@ -94,5 +94,5 @@ fn check(table: &Table) -> bool { if full { println!("Game is over. It's a draw"); } - return full; + full } diff --git a/src/cell.rs b/src/cell.rs index 18aadd0..fd0e0f0 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -23,7 +23,7 @@ impl Cell { /// Create a new `Cell` initialized with content from `string`. /// Text alignment in cell is configurable with the `align` argument pub fn new_align(string: &str, align: Alignment) -> Cell { - let content: Vec = string.lines().map(|ref x| x.to_string()).collect(); + let content: Vec = string.lines().map(|x| x.to_string()).collect(); let mut width = 0; for cont in &content { let l = UnicodeWidthStr::width(&cont[..]); @@ -109,29 +109,29 @@ impl Cell { let mut background = false; for c in spec.chars() { if foreground || background { - let color = match c { - 'r' => color::RED, - 'R' => color::BRIGHT_RED, - 'b' => color::BLUE, - 'B' => color::BRIGHT_BLUE, - 'g' => color::GREEN, - 'G' => color::BRIGHT_GREEN, - 'y' => color::YELLOW, - 'Y' => color::BRIGHT_YELLOW, - 'c' => color::CYAN, - 'C' => color::BRIGHT_CYAN, - 'm' => color::MAGENTA, - 'M' => color::BRIGHT_MAGENTA, - 'w' => color::WHITE, - 'W' => color::BRIGHT_WHITE, - 'd' => color::BLACK, - 'D' => color::BRIGHT_BLACK, + let color = match c { + 'r' => color::RED, + 'R' => color::BRIGHT_RED, + 'b' => color::BLUE, + 'B' => color::BRIGHT_BLUE, + 'g' => color::GREEN, + 'G' => color::BRIGHT_GREEN, + 'y' => color::YELLOW, + 'Y' => color::BRIGHT_YELLOW, + 'c' => color::CYAN, + 'C' => color::BRIGHT_CYAN, + 'm' => color::MAGENTA, + 'M' => color::BRIGHT_MAGENTA, + 'w' => color::WHITE, + 'W' => color::BRIGHT_WHITE, + 'd' => color::BLACK, + 'D' => color::BRIGHT_BLACK, _ => { // Silently ignore unknown tags foreground = false; background = false; continue; - } + } }; if foreground { self.style(Attr::ForegroundColor(color)); @@ -141,21 +141,20 @@ impl Cell { foreground = false; background = false; } else { - match c { - 'F' => foreground = true, - 'B' => background = true, - 'b' => self.style(Attr::Bold), - 'i' => self.style(Attr::Italic(true)), - 'u' => self.style(Attr::Underline(true)), - 'c' => self.align(Alignment::CENTER), - 'l' => self.align(Alignment::LEFT), - 'r' => self.align(Alignment::RIGHT), - 'd' => { /* Default : do nothing */ } - _ => { /* Silently ignore unknown tags */ } + match c { + 'F' => foreground = true, + 'B' => background = true, + 'b' => self.style(Attr::Bold), + 'i' => self.style(Attr::Italic(true)), + 'u' => self.style(Attr::Underline(true)), + 'c' => self.align(Alignment::CENTER), + 'l' => self.align(Alignment::LEFT), + 'r' => self.align(Alignment::RIGHT), + _ => { /* Silently ignore unknown tags */ } } } } - return self; + self } /// Return the height of the cell @@ -195,27 +194,27 @@ impl Cell { skip_right_fill: bool) -> Result<(), Error> { for a in &self.style { - match out.attr(a.clone()) { + match out.attr(*a) { Ok(..) | Err(::term::Error::NotSupported) | - Err(::term::Error::ColorOutOfRange) => (), // Ignore unsupported atrributes - Err(e) => return Err(term_error_to_io_error(e)), + Err(::term::Error::ColorOutOfRange) => (), // Ignore unsupported atrributes + Err(e) => return Err(term_error_to_io_error(e)), }; } try!(self.print(out, idx, col_width, skip_right_fill)); - match out.reset() { + match out.reset() { Ok(..) | Err(::term::Error::NotSupported) | - Err(::term::Error::ColorOutOfRange) => Ok(()), - Err(e) => Err(term_error_to_io_error(e)), + Err(::term::Error::ColorOutOfRange) => Ok(()), + Err(e) => Err(term_error_to_io_error(e)), } } } fn term_error_to_io_error(te: ::term::Error) -> Error { - match te { - ::term::Error::Io(why) => why, - _ => Error::new(::std::io::ErrorKind::Other, te), + match te { + ::term::Error::Io(why) => why, + _ => Error::new(::std::io::ErrorKind::Other, te), } } @@ -257,7 +256,7 @@ impl Default for Cell { /// ``` /// Value must implement the `std::string::ToString` trait /// -/// For details about style specifier syntax, check doc for [Cell::style_spec](cell/struct.Cell.html#method.style_spec) method +/// For details about style specifier syntax, check doc for [`Cell::style_spec`](cell/struct.Cell.html#method.style_spec) method /// # Example /// ``` /// # #[macro_use] extern crate prettytable; @@ -271,10 +270,10 @@ impl Default for Cell { /// # } /// ``` #[macro_export] -macro_rules! cell { - () => ($crate::cell::Cell::default()); - ($value:expr) => ($crate::cell::Cell::new(&$value.to_string())); - ($style:ident -> $value:expr) => (cell!($value).style_spec(stringify!($style))); +macro_rules! cell { + () => ($crate::cell::Cell::default()); + ($value:expr) => ($crate::cell::Cell::new(&$value.to_string())); + ($style:ident -> $value:expr) => (cell!($value).style_spec(stringify!($style))); } #[cfg(test)] diff --git a/src/format.rs b/src/format.rs index 25f477e..4160737 100644 --- a/src/format.rs +++ b/src/format.rs @@ -9,25 +9,36 @@ use super::utils::NEWLINE; /// Alignment for cell's content #[derive(Clone, Debug, PartialEq, Copy)] pub enum Alignment { + /// Align left LEFT, + /// Align in the center CENTER, + /// Align right RIGHT, } /// Position of a line separator in a table #[derive(Clone, Debug, PartialEq, Copy)] pub enum LinePosition { + /// Table's border on top Top, + /// Line separator between the titles row, + /// and the first data row Title, + /// Line separator between data rows Intern, + /// Bottom table's border Bottom, } /// Position of a column separator in a row #[derive(Clone, Debug, PartialEq, Copy)] pub enum ColumnPosition { + /// Left table's border Left, + /// Internal column separators Intern, + /// Rigth table's border Right, } @@ -164,11 +175,11 @@ impl TableFormat { /// Set a line separator pub fn separator(&mut self, what: LinePosition, separator: LineSeparator) { - *match what { - LinePosition::Top => &mut self.top_sep, - LinePosition::Bottom => &mut self.bottom_sep, - LinePosition::Title => &mut self.tsep, - LinePosition::Intern => &mut self.lsep, + *match what { + LinePosition::Top => &mut self.top_sep, + LinePosition::Bottom => &mut self.bottom_sep, + LinePosition::Title => &mut self.tsep, + LinePosition::Intern => &mut self.lsep, } = Some(separator); } @@ -180,16 +191,16 @@ impl TableFormat { } fn get_sep_for_line(&self, pos: LinePosition) -> &Option { - match pos { - LinePosition::Intern => return &self.lsep, - LinePosition::Top => return &self.top_sep, - LinePosition::Bottom => return &self.bottom_sep, + match pos { + LinePosition::Intern => &self.lsep, + LinePosition::Top => &self.top_sep, + LinePosition::Bottom => &self.bottom_sep, LinePosition::Title => { - match &self.tsep { - s @ &Some(_) => s, - &None => &self.lsep, + match &self.tsep { + s @ &Some(_) => s, + &None => &self.lsep, } - } + } } } @@ -199,7 +210,7 @@ impl TableFormat { col_width: &[usize], pos: LinePosition) -> Result<(), Error> { - match *self.get_sep_for_line(pos) { + match *self.get_sep_for_line(pos) { Some(ref l) => { l._print(out, col_width, @@ -207,16 +218,18 @@ impl TableFormat { self.csep.is_some(), self.lborder.is_some(), self.rborder.is_some()) - } - None => Ok(()), + } + None => Ok(()), } } + /// Returns the character used to separate columns. + /// `pos` specify if the separator is left/right final or internal to the table pub fn get_column_separator(&self, pos: ColumnPosition) -> Option { - match pos { - ColumnPosition::Left => self.lborder, - ColumnPosition::Intern => self.csep, - ColumnPosition::Right => self.rborder, + match pos { + ColumnPosition::Left => self.lborder, + ColumnPosition::Intern => self.csep, + ColumnPosition::Right => self.rborder, } } @@ -225,9 +238,9 @@ impl TableFormat { out: &mut T, pos: ColumnPosition) -> Result<(), Error> { - match self.get_column_separator(pos) { - Some(s) => out.write_all(Utf8Char::from(s).as_bytes()), - None => Ok(()), + match self.get_column_separator(pos) { + Some(s) => out.write_all(Utf8Char::from(s).as_bytes()), + None => Ok(()), } } } @@ -244,6 +257,7 @@ pub struct FormatBuilder { } impl FormatBuilder { + /// Creates a new builder pub fn new() -> FormatBuilder { FormatBuilder { format: Box::new(TableFormat::new()) } } @@ -289,175 +303,175 @@ impl FormatBuilder { pub mod consts { use super::{TableFormat, LineSeparator, FormatBuilder, LinePosition}; - lazy_static! { - /// A line separator made of `-` and `+` - static ref MINUS_PLUS_SEP: LineSeparator = LineSeparator::new('-', '+', '+', '+'); - /// A line separator made of `=` and `+` - static ref EQU_PLUS_SEP: LineSeparator = LineSeparator::new('=', '+', '+', '+'); - - /// Default table format - /// - /// # Example - /// ```text - /// +----+----+ - /// | T1 | T2 | - /// +====+====+ - /// | a | b | - /// +----+----+ - /// | d | c | - /// +----+----+ - /// ``` - pub static ref FORMAT_DEFAULT: TableFormat = FormatBuilder::new() - .column_separator('|') - .borders('|') - .separator(LinePosition::Intern, *MINUS_PLUS_SEP) - .separator(LinePosition::Title, *EQU_PLUS_SEP) - .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) - .separator(LinePosition::Top, *MINUS_PLUS_SEP) - .padding(1, 1) - .build(); - - /// Similar to `FORMAT_DEFAULT` but without special separator after title line - /// - /// # Example - /// ```text - /// +----+----+ - /// | T1 | T2 | - /// +----+----+ - /// | a | b | - /// +----+----+ - /// | c | d | - /// +----+----+ - /// ``` - pub static ref FORMAT_NO_TITLE: TableFormat = FormatBuilder::new() - .column_separator('|') - .borders('|') - .separator(LinePosition::Intern, *MINUS_PLUS_SEP) - .separator(LinePosition::Title, *MINUS_PLUS_SEP) - .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) - .separator(LinePosition::Top, *MINUS_PLUS_SEP) - .padding(1, 1) - .build(); - - /// With no line separator, but with title separator - /// - /// # Example - /// ```text - /// +----+----+ - /// | T1 | T2 | - /// +----+----+ - /// | a | b | - /// | c | d | - /// +----+----+ - /// ``` - pub static ref FORMAT_NO_LINESEP_WITH_TITLE: TableFormat = FormatBuilder::new() - .column_separator('|') - .borders('|') - .separator(LinePosition::Title, *MINUS_PLUS_SEP) - .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) - .separator(LinePosition::Top, *MINUS_PLUS_SEP) - .padding(1, 1) - .build(); - - /// With no line or title separator - /// - /// # Example - /// ```text - /// +----+----+ - /// | T1 | T2 | - /// | a | b | - /// | c | d | - /// +----+----+ - /// ``` - pub static ref FORMAT_NO_LINESEP: TableFormat = FormatBuilder::new() - .column_separator('|') - .borders('|') - .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) - .separator(LinePosition::Top, *MINUS_PLUS_SEP) - .padding(1, 1) - .build(); - - /// No column separator - /// - /// # Example - /// ```text - /// -------- - /// T1 T2 - /// ======== - /// a b - /// -------- - /// d c - /// -------- - /// ``` - pub static ref FORMAT_NO_COLSEP: TableFormat = FormatBuilder::new() - .separator(LinePosition::Intern, *MINUS_PLUS_SEP) - .separator(LinePosition::Title, *EQU_PLUS_SEP) - .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) - .separator(LinePosition::Top, *MINUS_PLUS_SEP) - .padding(1, 1) - .build(); - - /// Format for printing a table without any separators (only alignment) - /// - /// # Example - /// ```text - /// T1 T2 - /// a b - /// d c - /// ``` - pub static ref FORMAT_CLEAN: TableFormat = FormatBuilder::new() - .padding(1, 1) - .build(); - - /// Format for a table with only external borders and title separator - /// - /// # Example - /// ```text - /// +--------+ - /// | T1 T2 | - /// +========+ - /// | a b | - /// | c d | - /// +--------+ - /// ``` - pub static ref FORMAT_BORDERS_ONLY: TableFormat = FormatBuilder::new() - .padding(1, 1) - .separator(LinePosition::Title, *EQU_PLUS_SEP) - .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) - .separator(LinePosition::Top, *MINUS_PLUS_SEP) - .borders('|') - .build(); - - /// A table with no external border - /// - /// # Example - /// ```text - /// T1 | T2 - /// ====+==== - /// a | b - /// ----+---- - /// c | d - /// ``` - pub static ref FORMAT_NO_BORDER: TableFormat = FormatBuilder::new() - .padding(1, 1) - .separator(LinePosition::Intern, *MINUS_PLUS_SEP) - .separator(LinePosition::Title, *EQU_PLUS_SEP) - .column_separator('|') - .build(); - - /// A table with no external border and no line separation - /// - /// # Example - /// ```text - /// T1 | T2 - /// ----+---- - /// a | b - /// c | d - /// ``` - pub static ref FORMAT_NO_BORDER_LINE_SEPARATOR: TableFormat = FormatBuilder::new() - .padding(1, 1) - .separator(LinePosition::Title, *MINUS_PLUS_SEP) - .column_separator('|') - .build(); + lazy_static! { + /// A line separator made of `-` and `+` + static ref MINUS_PLUS_SEP: LineSeparator = LineSeparator::new('-', '+', '+', '+'); + /// A line separator made of `=` and `+` + static ref EQU_PLUS_SEP: LineSeparator = LineSeparator::new('=', '+', '+', '+'); + + /// Default table format + /// + /// # Example + /// ```text + /// +----+----+ + /// | T1 | T2 | + /// +====+====+ + /// | a | b | + /// +----+----+ + /// | d | c | + /// +----+----+ + /// ``` + pub static ref FORMAT_DEFAULT: TableFormat = FormatBuilder::new() + .column_separator('|') + .borders('|') + .separator(LinePosition::Intern, *MINUS_PLUS_SEP) + .separator(LinePosition::Title, *EQU_PLUS_SEP) + .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) + .separator(LinePosition::Top, *MINUS_PLUS_SEP) + .padding(1, 1) + .build(); + + /// Similar to `FORMAT_DEFAULT` but without special separator after title line + /// + /// # Example + /// ```text + /// +----+----+ + /// | T1 | T2 | + /// +----+----+ + /// | a | b | + /// +----+----+ + /// | c | d | + /// +----+----+ + /// ``` + pub static ref FORMAT_NO_TITLE: TableFormat = FormatBuilder::new() + .column_separator('|') + .borders('|') + .separator(LinePosition::Intern, *MINUS_PLUS_SEP) + .separator(LinePosition::Title, *MINUS_PLUS_SEP) + .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) + .separator(LinePosition::Top, *MINUS_PLUS_SEP) + .padding(1, 1) + .build(); + + /// With no line separator, but with title separator + /// + /// # Example + /// ```text + /// +----+----+ + /// | T1 | T2 | + /// +----+----+ + /// | a | b | + /// | c | d | + /// +----+----+ + /// ``` + pub static ref FORMAT_NO_LINESEP_WITH_TITLE: TableFormat = FormatBuilder::new() + .column_separator('|') + .borders('|') + .separator(LinePosition::Title, *MINUS_PLUS_SEP) + .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) + .separator(LinePosition::Top, *MINUS_PLUS_SEP) + .padding(1, 1) + .build(); + + /// With no line or title separator + /// + /// # Example + /// ```text + /// +----+----+ + /// | T1 | T2 | + /// | a | b | + /// | c | d | + /// +----+----+ + /// ``` + pub static ref FORMAT_NO_LINESEP: TableFormat = FormatBuilder::new() + .column_separator('|') + .borders('|') + .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) + .separator(LinePosition::Top, *MINUS_PLUS_SEP) + .padding(1, 1) + .build(); + + /// No column separator + /// + /// # Example + /// ```text + /// -------- + /// T1 T2 + /// ======== + /// a b + /// -------- + /// d c + /// -------- + /// ``` + pub static ref FORMAT_NO_COLSEP: TableFormat = FormatBuilder::new() + .separator(LinePosition::Intern, *MINUS_PLUS_SEP) + .separator(LinePosition::Title, *EQU_PLUS_SEP) + .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) + .separator(LinePosition::Top, *MINUS_PLUS_SEP) + .padding(1, 1) + .build(); + + /// Format for printing a table without any separators (only alignment) + /// + /// # Example + /// ```text + /// T1 T2 + /// a b + /// d c + /// ``` + pub static ref FORMAT_CLEAN: TableFormat = FormatBuilder::new() + .padding(1, 1) + .build(); + + /// Format for a table with only external borders and title separator + /// + /// # Example + /// ```text + /// +--------+ + /// | T1 T2 | + /// +========+ + /// | a b | + /// | c d | + /// +--------+ + /// ``` + pub static ref FORMAT_BORDERS_ONLY: TableFormat = FormatBuilder::new() + .padding(1, 1) + .separator(LinePosition::Title, *EQU_PLUS_SEP) + .separator(LinePosition::Bottom, *MINUS_PLUS_SEP) + .separator(LinePosition::Top, *MINUS_PLUS_SEP) + .borders('|') + .build(); + + /// A table with no external border + /// + /// # Example + /// ```text + /// T1 | T2 + /// ====+==== + /// a | b + /// ----+---- + /// c | d + /// ``` + pub static ref FORMAT_NO_BORDER: TableFormat = FormatBuilder::new() + .padding(1, 1) + .separator(LinePosition::Intern, *MINUS_PLUS_SEP) + .separator(LinePosition::Title, *EQU_PLUS_SEP) + .column_separator('|') + .build(); + + /// A table with no external border and no line separation + /// + /// # Example + /// ```text + /// T1 | T2 + /// ----+---- + /// a | b + /// c | d + /// ``` + pub static ref FORMAT_NO_BORDER_LINE_SEPARATOR: TableFormat = FormatBuilder::new() + .padding(1, 1) + .separator(LinePosition::Title, *MINUS_PLUS_SEP) + .column_separator('|') + .build(); } } diff --git a/src/lib.rs b/src/lib.rs index c0184bd..f825e23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,7 @@ +#![warn(missing_docs, + unused_extern_crates, + unused_import_braces, + unused_qualifications)] //! A formatted and aligned table printer written in rust extern crate unicode_width; extern crate term; @@ -83,6 +87,11 @@ impl<'a> TableSlice<'a> { self.rows.len() } + /// Check if the table slice is empty + pub fn is_empty(&self) -> bool { + self.rows.is_empty() + } + /// Get an immutable reference to a row pub fn get_row(&self, row: usize) -> Option<&Row> { self.rows.get(row) @@ -91,9 +100,9 @@ impl<'a> TableSlice<'a> { /// Get the width of the column at position `col_idx`. /// Return 0 if the column does not exists; fn get_column_width(&self, col_idx: usize) -> usize { - let mut width = match *self.titles { - Some(ref t) => t.get_cell_width(col_idx), - None => 0, + let mut width = match *self.titles { + Some(ref t) => t.get_cell_width(col_idx), + None => 0, }; for r in self.rows { let l = r.get_cell_width(col_idx); @@ -134,14 +143,14 @@ impl<'a> TableSlice<'a> { try!(self.format .print_line_separator(out, &col_width, LinePosition::Top)); if let Some(ref t) = *self.titles { - try!(f(t, out, &self.format, &col_width)); + try!(f(t, out, self.format, &col_width)); try!(self.format .print_line_separator(out, &col_width, LinePosition::Title)); } // Print rows let mut iter = self.rows.into_iter().peekable(); while let Some(r) = iter.next() { - try!(f(r, out, &self.format, &col_width)); + try!(f(r, out, self.format, &col_width)); if iter.peek().is_some() { try!(self.format .print_line_separator(out, &col_width, LinePosition::Intern)); @@ -171,9 +180,9 @@ impl<'a> TableSlice<'a> { /// # Panic /// Panic if writing to standard output fails pub fn print_tty(&self, force_colorize: bool) { - let r = match (stdout(), atty::is(atty::Stream::Stdout) || force_colorize) { - (Some(mut o), true) => self.print_term(&mut *o), - _ => self.print(&mut io::stdout()), + let r = match (stdout(), atty::is(atty::Stream::Stdout) || force_colorize) { + (Some(mut o), true) => self.print_term(&mut *o), + _ => self.print(&mut io::stdout()), }; if let Err(e) = r { panic!("Cannot print table to standard output : {}", e); @@ -284,6 +293,11 @@ impl Table { self.rows.len() } + /// Check if the table is empty + pub fn is_empty(&self) -> bool { + self.rows.is_empty() + } + /// Set the optional title lines pub fn set_titles(&mut self, titles: Row) { *self.titles = Some(titles); @@ -353,12 +367,12 @@ impl Table { } /// Returns an iterator over immutable rows - pub fn row_iter<'a>(&'a self) -> Iter<'a, Row> { + pub fn row_iter(&self) -> Iter { self.rows.iter() } /// Returns an iterator over mutable rows - pub fn row_iter_mut<'a>(&'a mut self) -> IterMut<'a, Row> { + pub fn row_iter_mut(&mut self) -> IterMut { self.rows.iter_mut() } @@ -439,7 +453,7 @@ impl fmt::Display for Table { impl<'a> fmt::Display for TableSlice<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { let mut writer = StringWriter::new(); - if let Err(_) = self.print(&mut writer) { + if self.print(&mut writer).is_err() { return Err(fmt::Error); } fmt.write_str(writer.as_string()) @@ -450,7 +464,7 @@ impl> FromIterator for Table { fn from_iter(iterator: T) -> Table where T: IntoIterator { - Self::init(iterator.into_iter().map(|r| Row::from(r)).collect()) + Self::init(iterator.into_iter().map(Row::from).collect()) } } @@ -481,9 +495,9 @@ impl<'a> IntoIterator for &'a mut Table { } /// Iterator over immutable cells in a column -pub struct ColumnIter<'a>(std::slice::Iter<'a, Row>, usize); +pub struct ColumnIter<'a>(Iter<'a, Row>, usize); -impl<'a> std::iter::Iterator for ColumnIter<'a> { +impl<'a> Iterator for ColumnIter<'a> { type Item = &'a Cell; fn next(&mut self) -> Option<&'a Cell> { self.0.next().and_then(|row| row.get_cell(self.1)) @@ -491,9 +505,9 @@ impl<'a> std::iter::Iterator for ColumnIter<'a> { } /// Iterator over mutable cells in a column -pub struct ColumnIterMut<'a>(std::slice::IterMut<'a, Row>, usize); +pub struct ColumnIterMut<'a>(IterMut<'a, Row>, usize); -impl<'a> std::iter::Iterator for ColumnIterMut<'a> { +impl<'a> Iterator for ColumnIterMut<'a> { type Item = &'a mut Cell; fn next(&mut self) -> Option<&'a mut Cell> { self.0.next().and_then(|row| row.get_mut_cell(self.1)) @@ -574,26 +588,26 @@ impl<'a, T, E> Slice<'a, E> for T /// # } /// ``` /// -/// For details about style specifier syntax, check doc for [Cell::style_spec](cell/struct.Cell.html#method.style_spec) method +/// For details about style specifier syntax, check doc for [`Cell::style_spec`](cell/struct.Cell.html#method.style_spec) method #[macro_export] -macro_rules! table { - ($([$($content:tt)*]), *) => ( - $crate::Table::init(vec![$(row![$($content)*]), *]) - ); +macro_rules! table { + ($([$($content:tt)*]), *) => ( + $crate::Table::init(vec![$(row![$($content)*]), *]) + ); } /// Create a table with `table!` macro, print it to standard output, then return this table for future usage. /// /// The syntax is the same that the one for the `table!` macro #[macro_export] -macro_rules! ptable { - ($($content:tt)*) => ( - { - let tab = table!($($content)*); - tab.printstd(); - tab - } - ); +macro_rules! ptable { + ($($content:tt)*) => ( + { + let tab = table!($($content)*); + tab.printstd(); + tab + } + ); } #[cfg(test)] @@ -611,14 +625,14 @@ mod tests { table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")])); table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")])); table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")])); - let out = "\ -+-----+----+-----+ -| t1 | t2 | t3 | -+=====+====+=====+ -| a | bc | def | -+-----+----+-----+ -| def | bc | a | -+-----+----+-----+ + let out = "\ ++-----+----+-----+ +| t1 | t2 | t3 | ++=====+====+=====+ +| a | bc | def | ++-----+----+-----+ +| def | bc | a | ++-----+----+-----+ "; assert_eq!(table.to_string().replace("\r\n", "\n"), out); } @@ -634,14 +648,14 @@ mod tests { table[1][1] = Cell::new("newval"); assert_eq!(table[1][1].get_content(), "newval"); - let out = "\ -+-----+--------+-----+ -| t1 | t2 | t3 | -+=====+========+=====+ -| a | bc | def | -+-----+--------+-----+ -| def | newval | a | -+-----+--------+-----+ + let out = "\ ++-----+--------+-----+ +| t1 | t2 | t3 | ++=====+========+=====+ +| a | bc | def | ++-----+--------+-----+ +| def | newval | a | ++-----+--------+-----+ "; assert_eq!(table.to_string().replace("\r\n", "\n"), out); } @@ -658,12 +672,12 @@ mod tests { table[1][1] = Cell::new("newval"); assert_eq!(table[1][1].get_content(), "newval"); - let out = "\ -+-----+--------+-----+ -| t1 | t2 | t3 | -| a | bc | def | -| def | newval | a | -+-----+--------+-----+ + let out = "\ ++-----+--------+-----+ +| t1 | t2 | t3 | +| a | bc | def | +| def | newval | a | ++-----+--------+-----+ "; assert_eq!(table.to_string().replace("\r\n", "\n"), out); } @@ -680,14 +694,14 @@ mod tests { table[1][1] = Cell::new("newval"); assert_eq!(table[1][1].get_content(), "newval"); - let out = "\ ------------------- - t1 t2 t3 \n\ -================== - a bc def \n\ ------------------- - def newval a \n\ ------------------- + let out = "\ +------------------ + t1 t2 t3 \n\ +================== + a bc def \n\ +------------------ + def newval a \n\ +------------------ "; println!("{}", out); println!("____"); @@ -707,10 +721,10 @@ mod tests { table[1][1] = Cell::new("newval"); assert_eq!(table[1][1].get_content(), "newval"); - let out = "\ -\u{0020}t1 t2 t3 \n\ -\u{0020}a bc def \n\ -\u{0020}def newval a \n\ + let out = "\ +\u{0020}t1 t2 t3 \n\ +\u{0020}a bc def \n\ +\u{0020}def newval a \n\ "; println!("{}", out); println!("____"); @@ -732,14 +746,14 @@ mod tests { table[1][1] = Cell::new("newval"); assert_eq!(table[1][1].get_content(), "newval"); - let out = "\ -+-------+----------+-------+ -| t1 | t2 | t3 | -+=======+==========+=======+ -| a | bc | def | -+-------+----------+-------+ -| def | newval | a | -+-------+----------+-------+ + let out = "\ ++-------+----------+-------+ +| t1 | t2 | t3 | ++=======+==========+=======+ +| a | bc | def | ++-------+----------+-------+ +| def | newval | a | ++-------+----------+-------+ "; println!("{}", out); println!("____"); @@ -757,16 +771,16 @@ mod tests { table.add_row(Row::new(vec![Cell::new("3"), Cell::new("3"), Cell::new("3")])); table.add_row(Row::new(vec![Cell::new("4"), Cell::new("4"), Cell::new("4")])); table.add_row(Row::new(vec![Cell::new("5"), Cell::new("5"), Cell::new("5")])); - let out = "\ -+----+----+----+ -| t1 | t2 | t3 | -+====+====+====+ -| 1 | 1 | 1 | -+----+----+----+ -| 2 | 2 | 2 | -+----+----+----+ -| 3 | 3 | 3 | -+----+----+----+ + let out = "\ ++----+----+----+ +| t1 | t2 | t3 | ++====+====+====+ +| 1 | 1 | 1 | ++----+----+----+ +| 2 | 2 | 2 | ++----+----+----+ +| 3 | 3 | 3 | ++----+----+----+ "; let slice = table.slice(..); let slice = slice.slice(1..); @@ -801,14 +815,14 @@ mod tests { table.add_row(Row::new(vec![Cell::new("1"), Cell::new("1"), Cell::new("1")])); table.add_row(Row::new(vec![Cell::new("2"), Cell::new("2"), Cell::new("2")])); table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")])); - let out = "\ -┌────┬────┬────┐ -| t1 | t2 | t3 | -├────┼────┼────┤ -| 1 | 1 | 1 | -├────┼────┼────┤ -| 2 | 2 | 2 | -└────┴────┴────┘ + let out = "\ +┌────┬────┬────┐ +| t1 | t2 | t3 | +├────┼────┼────┤ +| 1 | 1 | 1 | +├────┼────┼────┤ +| 2 | 2 | 2 | +└────┴────┴────┘ "; println!("{}", out); println!("____"); @@ -822,8 +836,8 @@ mod tests { use row::Row; use cell::Cell; - static CSV_S: &'static str = "ABC,DEFG,HIJKLMN\n\ - foobar,bar,foo\n\ + static CSV_S: &'static str = "ABC,DEFG,HIJKLMN\n\ + foobar,bar,foo\n\ foobar2,bar2,foo2\n"; fn test_table() -> Table { diff --git a/src/main.rs b/src/main.rs index 9ee9b4d..52e53dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,12 +20,12 @@ fn main() { table.add_row(row![]); // Add style to a full row table.add_row(row![FY => "styled", "bar", "foo"]); - table.add_row(Row::new(vec![ - Cell::new("foobar2"), - // Create a cell with a red foreground color - Cell::new("bar2").with_style(Attr::ForegroundColor(color::RED)), - // Create a cell with red foreground color, yellow background color, with bold characters - Cell::new("foo2").style_spec("FrByb")]) + table.add_row(Row::new(vec![ + Cell::new("foobar2"), + // Create a cell with a red foreground color + Cell::new("bar2").with_style(Attr::ForegroundColor(color::RED)), + // Create a cell with red foreground color, yellow background color, with bold characters + Cell::new("foo2").style_spec("FrByb")]) ); for cell in table.column_iter_mut(2) { cell.align(Alignment::RIGHT); diff --git a/src/row.rs b/src/row.rs index 4e0975d..69647ce 100644 --- a/src/row.rs +++ b/src/row.rs @@ -32,6 +32,11 @@ impl Row { self.cells.len() } + /// Check if the row is empty (has no cell) + pub fn is_empty(&self) -> bool { + self.cells.is_empty() + } + /// Get the height of this row pub fn get_height(&self) -> usize { let mut height = 1; // Minimum height must be 1 to print empty rows @@ -95,12 +100,12 @@ impl Row { } /// Returns an immutable iterator over cells - pub fn iter<'a>(&'a self) -> Iter<'a, Cell> { + pub fn iter(&self) -> Iter { self.cells.iter() } /// Returns an mutable iterator over cells - pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Cell> { + pub fn iter_mut(&mut self) -> IterMut { self.cells.iter_mut() } @@ -117,14 +122,14 @@ impl Row { try!(format.print_column_separator(out, ColumnPosition::Left)); let (lp, rp) = format.get_padding(); for j in 0..col_width.len() { - try!(out.write(&vec![' ' as u8; lp])); + try!(out.write_all(&vec![b' '; lp])); let skip_r_fill = (j == col_width.len() - 1) && format.get_column_separator(ColumnPosition::Right).is_none(); - match self.get_cell(j) { - Some(ref c) => try!(f(c, out, i, col_width[j], skip_r_fill)), - None => try!(f(&Cell::default(), out, i, col_width[j], skip_r_fill)), + match self.get_cell(j) { + Some(c) => try!(f(c, out, i, col_width[j], skip_r_fill)), + None => try!(f(&Cell::default(), out, i, col_width[j], skip_r_fill)), }; - try!(out.write(&vec![' ' as u8; rp])); + try!(out.write_all(&vec![b' '; rp])); if j < col_width.len() - 1 { try!(format.print_column_separator(out, ColumnPosition::Intern)); } @@ -229,15 +234,15 @@ impl<'a> IntoIterator for &'a mut Row { /// # } /// ``` /// -/// For details about style specifier syntax, check doc for [Cell::style_spec](cell/struct.Cell.html#method.style_spec) method +/// For details about style specifier syntax, check doc for [`Cell::style_spec`](cell/struct.Cell.html#method.style_spec) method #[macro_export] -macro_rules! row { - (($($out:tt)*); $value:expr) => (vec![$($out)* cell!($value)]); - (($($out:tt)*); $value:expr, $($n:tt)*) => (row!(($($out)* cell!($value),); $($n)*)); - (($($out:tt)*); $style:ident -> $value:expr) => (vec![$($out)* cell!($style -> $value)]); - (($($out:tt)*); $style:ident -> $value:expr, $($n: tt)*) => (row!(($($out)* cell!($style -> $value),); $($n)*)); - - ($($content:expr), *) => ($crate::row::Row::new(vec![$(cell!($content)), *])); - ($style:ident => $($content:expr), *) => ($crate::row::Row::new(vec![$(cell!($style -> $content)), *])); - ($($content:tt)*) => ($crate::row::Row::new(row!((); $($content)*))); +macro_rules! row { + (($($out:tt)*); $value:expr) => (vec![$($out)* cell!($value)]); + (($($out:tt)*); $value:expr, $($n:tt)*) => (row!(($($out)* cell!($value),); $($n)*)); + (($($out:tt)*); $style:ident -> $value:expr) => (vec![$($out)* cell!($style -> $value)]); + (($($out:tt)*); $style:ident -> $value:expr, $($n: tt)*) => (row!(($($out)* cell!($style -> $value),); $($n)*)); + + ($($content:expr), *) => ($crate::row::Row::new(vec![$(cell!($content)), *])); + ($style:ident => $($content:expr), *) => ($crate::row::Row::new(vec![$(cell!($style -> $content)), *])); + ($($content:tt)*) => ($crate::row::Row::new(row!((); $($content)*))); } diff --git a/src/utils.rs b/src/utils.rs index 8f4bbf3..c00b2d7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -30,12 +30,12 @@ impl StringWriter { impl Write for StringWriter { fn write(&mut self, data: &[u8]) -> Result { - let string = match str::from_utf8(data) { - Ok(s) => s, + let string = match str::from_utf8(data) { + Ok(s) => s, Err(e) => { return Err(Error::new(ErrorKind::Other, format!("Cannot decode utf8 string : {}", e))) - } + } }; self.string.push_str(string); Ok(data.len()) @@ -59,18 +59,18 @@ pub fn print_align(out: &mut T, -> Result<(), Error> { let text_len = UnicodeWidthStr::width(text); let mut nfill = if text_len < size { size - text_len } else { 0 }; - let n = match align { - Alignment::LEFT => 0, - Alignment::RIGHT => nfill, - Alignment::CENTER => nfill / 2, + let n = match align { + Alignment::LEFT => 0, + Alignment::RIGHT => nfill, + Alignment::CENTER => nfill / 2, }; if n > 0 { - try!(out.write(&vec![fill as u8; n])); + try!(out.write_all(&vec![fill as u8; n])); nfill -= n; } - try!(out.write(text.as_bytes())); + try!(out.write_all(text.as_bytes())); if nfill > 0 && !skip_right_fill { - try!(out.write(&vec![fill as u8; nfill])); + try!(out.write_all(&vec![fill as u8; nfill])); } Ok(()) } -- cgit v1.2.3