summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpierresy <pierre-henri.symoneaux@alcatel-lucent.com>2016-01-17 23:35:25 +0100
committerpierresy <pierre-henri.symoneaux@alcatel-lucent.com>2016-01-18 18:02:08 +0100
commit65aedffc22c05b4b00d6e14c6711bd905a435e40 (patch)
tree8f32ebcedbb401945bcd5206f8263773c8358202
parent8fbd2af468da9eddf2f2e21238141212f4c88e88 (diff)
Started Builder implementation
Constant predefined format are now lazily evaluated
-rw-r--r--Cargo.toml1
-rw-r--r--src/format.rs192
-rw-r--r--src/lib.rs13
-rw-r--r--src/main.rs2
4 files changed, 161 insertions, 47 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 8954c84..28c4727 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,3 +21,4 @@ name = "prettytable"
[dependencies]
unicode-width = "^0.1"
term = "^0.4"
+lazy_static = "^0.1"
diff --git a/src/format.rs b/src/format.rs
index 3d879f1..facc7d5 100644
--- a/src/format.rs
+++ b/src/format.rs
@@ -30,7 +30,7 @@ pub enum ColumnPosition {
}
/// Contains the character used for printing a line separator
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, Copy)]
pub struct LineSeparator {
/// Line separator
line: char,
@@ -76,7 +76,7 @@ impl Default for LineSeparator {
}
/// Contains the table formatting rules
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, Copy)]
pub struct TableFormat {
/// Optional column separator character
csep: Option<char>,
@@ -98,12 +98,6 @@ pub struct TableFormat {
pad_right: usize
}
-impl Default for TableFormat {
- fn default() -> Self {
- return TableFormat::new(None, None, None);
- }
-}
-
impl TableFormat {
/// Create a new TableFormat.
@@ -126,10 +120,37 @@ impl TableFormat {
};
}
+ /// Return a tuple with left and right padding
pub fn get_padding(&self) -> (usize, usize) {
return (self.pad_left, self.pad_right);
}
+ /// Set left and right padding
+ pub fn padding(&mut self, left: usize, right: usize) {
+ self.pad_left = left;
+ self.pad_right = right;
+ }
+
+ /// Set the character used for internal column separation
+ pub fn column_separator(&mut self, separator: char) {
+ self.csep = Some(separator);
+ }
+
+ /// Set the character used for table borders
+ pub fn borders(&mut self, border: char) {
+ self.lborder = Some(border);
+ self.rborder = Some(border);
+ }
+
+ 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
+ } = Some(separator);
+ }
+
fn get_sep_for_line(&self, pos: LinePosition) -> &Option<LineSeparator> {
return match pos {
LinePosition::Intern => return &self.lsep,
@@ -167,35 +188,126 @@ impl TableFormat {
}
}
-/// A line separator mad of `-` and `+`
-pub const MINUS_PLUS_SEP: LineSeparator = LineSeparator{line: '-', junc: '+', ljunc: '+', rjunc: '+'};
-/// A line separator mad of `=` and `+`
-pub const EQU_PLUS_SEP: LineSeparator = LineSeparator{line: '=', junc: '+', ljunc: '+', rjunc: '+'};
-
-/// Default table format, printing a table like this :
-///
-/// ```text
-/// +----+----+
-/// | T1 | T2 |
-/// +====+====+
-/// | | |
-/// +----+----+
-/// | | |
-/// +----+----+
-/// ```
-pub const FORMAT_DEFAULT: TableFormat = TableFormat{csep: Some('|'), lborder: Some('|'), rborder: Some('|'), lsep: Some(MINUS_PLUS_SEP), tsep: Some(EQU_PLUS_SEP), top_sep: Some(MINUS_PLUS_SEP), bottom_sep: Some(MINUS_PLUS_SEP), pad_left: 1, pad_right: 1};
-
-/// Similar to `FORMAT_DEFAULT` but without special separator after title line
-pub const FORMAT_NO_TITLE: TableFormat = TableFormat{csep: Some('|'), lborder: Some('|'), rborder: Some('|'), lsep: Some(MINUS_PLUS_SEP), tsep: Some(MINUS_PLUS_SEP), top_sep: Some(MINUS_PLUS_SEP), bottom_sep: Some(MINUS_PLUS_SEP), pad_left: 1, pad_right: 1};
-
-/// With no line separator, but with title separator
-pub const FORMAT_NO_LINESEP_WITH_TITLE: TableFormat = TableFormat{csep: Some('|'), lborder: Some('|'), rborder: Some('|'), lsep: None, tsep: Some(MINUS_PLUS_SEP), top_sep: Some(MINUS_PLUS_SEP), bottom_sep: Some(MINUS_PLUS_SEP), pad_left: 1, pad_right: 1};
-
-/// With no line or title separator
-pub const FORMAT_NO_LINESEP: TableFormat = TableFormat{csep: Some('|'), lborder: Some('|'), rborder: Some('|'), lsep: None, tsep: None, top_sep: None, bottom_sep: None, pad_left: 1, pad_right: 1};
-
-/// No column seprarator
-pub const FORMAT_NO_COLSEP: TableFormat = TableFormat{csep: None, lborder: None, rborder: None, lsep: Some(MINUS_PLUS_SEP), tsep: Some(EQU_PLUS_SEP), top_sep: Some(MINUS_PLUS_SEP), bottom_sep: Some(MINUS_PLUS_SEP), pad_left: 1, pad_right: 1};
-
-/// Format for printing a table without any separators (only alignment)
-pub const FORMAT_NO_BORDER: TableFormat = TableFormat{csep: None, lborder: None, rborder: None, lsep: None, tsep: None, top_sep: None, bottom_sep: None, pad_left: 1, pad_right: 1};
+impl Default for TableFormat {
+ fn default() -> Self {
+ return TableFormat::new(None, None, None);
+ }
+}
+
+/// A builder to create a `Table Format`
+pub struct FormatBuilder {
+ format: Box<TableFormat>
+}
+
+impl FormatBuilder {
+ pub fn new() -> FormatBuilder {
+ return FormatBuilder {
+ format: Box::new(TableFormat::new(None, None, None))
+ };
+ }
+
+ /// Set left and right padding
+ pub fn padding(mut self, left: usize, right: usize) -> Self {
+ self.format.padding(left, right);
+ return self;
+ }
+
+ /// Set the character used for internal column separation
+ pub fn column_separator(mut self, separator: char) -> Self {
+ self.format.column_separator(separator);
+ return self;
+ }
+
+ /// Set the character used for table borders
+ pub fn borders(mut self, border: char) -> Self {
+ self.format.borders(border);
+ return self;
+ }
+
+ /// Set a line separator format
+ pub fn separator(mut self, what: LinePosition, separator: LineSeparator) -> Self {
+ self.format.separator(what, separator);
+ return self;
+ }
+
+ /// Consume this builder and return the generated `TableFormat`
+ pub fn build(self) -> TableFormat {
+ return *self.format;
+ }
+}
+
+/// Predifined formats. Those constants are lazily evaluated when
+/// the corresponding struct is dereferenced
+pub mod consts {
+ use super::{TableFormat, LineSeparator, FormatBuilder, LinePosition};
+
+ lazy_static! {
+ /// A line separator made of `-` and `+`
+ pub static ref MINUS_PLUS_SEP: LineSeparator = LineSeparator::new('-', '+', '+', '+');
+ /// A line separator made of `=` and `+`
+ pub static ref EQU_PLUS_SEP: LineSeparator = LineSeparator::new('=', '+', '+', '+');
+
+ /// Default table format, printing a table like this :
+ ///
+ /// ```text
+ /// +----+----+
+ /// | T1 | T2 |
+ /// +====+====+
+ /// | | |
+ /// +----+----+
+ /// | | |
+ /// +----+----+
+ /// ```
+ 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
+ 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
+ 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
+ pub static ref FORMAT_NO_LINESEP: TableFormat = FormatBuilder::new()
+ .column_separator('|')
+ .borders('|')
+ .padding(1, 1)
+ .build();
+
+ /// No column separator
+ 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)
+ pub static ref FORMAT_NO_BORDER: TableFormat = FormatBuilder::new()
+ .padding(1, 1)
+ .build();
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 304825c..66f7477 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
//! A formatted and aligned table printer written in rust
extern crate unicode_width;
extern crate term;
+#[macro_use] extern crate lazy_static;
use std::io;
use std::io::{Write, Error};
@@ -18,7 +19,7 @@ mod utils;
use row::Row;
use cell::Cell;
-use format::{TableFormat, LinePosition, FORMAT_DEFAULT};
+use format::{TableFormat, LinePosition, consts};
use utils::StringWriter;
/// An owned printable table
@@ -167,7 +168,7 @@ impl Table {
return Table {
rows: rows,
titles: Box::new(None),
- format: Box::new(FORMAT_DEFAULT)
+ format: Box::new(*consts::FORMAT_DEFAULT)
};
}
@@ -457,7 +458,7 @@ mod tests {
use Slice;
use row::Row;
use cell::Cell;
- use format::{FORMAT_NO_LINESEP, FORMAT_NO_COLSEP, FORMAT_NO_BORDER};
+ use format::consts::{FORMAT_NO_LINESEP, FORMAT_NO_COLSEP, FORMAT_NO_BORDER};
#[test]
fn table() {
@@ -503,7 +504,7 @@ mod tests {
#[test]
fn no_linesep() {
let mut table = Table::new();
- table.set_format(FORMAT_NO_LINESEP);
+ table.set_format(*FORMAT_NO_LINESEP);
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")]));
@@ -523,7 +524,7 @@ mod tests {
#[test]
fn no_colsep() {
let mut table = Table::new();
- table.set_format(FORMAT_NO_COLSEP);
+ table.set_format(*FORMAT_NO_COLSEP);
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")]));
@@ -550,7 +551,7 @@ mod tests {
#[test]
fn no_borders() {
let mut table = Table::new();
- table.set_format(FORMAT_NO_BORDER);
+ table.set_format(*FORMAT_NO_BORDER);
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")]));
diff --git a/src/main.rs b/src/main.rs
index 78eac2d..ac29515 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -45,7 +45,7 @@ fn main() {
// You can also apply style to full rows :
let mut table = table!([Frb -> "A", "B", "C"], [1, 2, 3, 4], ["A\nBCCZZZ\nDDD", 2, table]);
table.set_titles(row!["Title 1", "Title 2"]);
- table.set_format(FORMAT_DEFAULT);
+ table.set_format(*consts::FORMAT_DEFAULT);
table.printstd();
// println!("{:#?}", table);
}