summaryrefslogtreecommitdiffstats
path: root/src/row.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/row.rs')
-rw-r--r--src/row.rs444
1 files changed, 232 insertions, 212 deletions
diff --git a/src/row.rs b/src/row.rs
index 653ab2b..4e0975d 100644
--- a/src/row.rs
+++ b/src/row.rs
@@ -1,216 +1,236 @@
-//! This module contains definition of table rows stuff
-use std::io::{Write, Error};
-use std::iter::FromIterator;
-use std::slice::{Iter, IterMut};
-use std::ops::{Index, IndexMut};
-
-use term::Terminal;
-
-use super::utils::NEWLINE;
-use super::cell::Cell;
-use super::format::{TableFormat, ColumnPosition};
-
-/// Represent a table row made of cells
-#[derive(Clone, Debug)]
-pub struct Row {
- cells: Vec<Cell>
-}
-
-impl Row {
- /// Create a new `Row` backed with `cells` vector
- pub fn new(cells: Vec<Cell>) -> Row {
- Row {
- cells: cells
- }
- }
-
- /// Create an row of length `size`, with empty strings stored
- pub fn empty() -> Row {
- Self::new(vec![Cell::default(); 0])
- }
-
- /// Get the number of cells in this row
- pub fn len(&self) -> usize {
- self.cells.len()
- }
-
- /// 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
- for cell in &self.cells {
- let h = cell.get_height();
- if h > height {
- height = h;
- }
- }
- height
- }
-
- /// Get the minimum width required by the cell in the column `column`.
- /// Return 0 if the cell does not exist in this row
- pub fn get_cell_width(&self, column: usize) -> usize {
- self.cells.get(column).map(|cell| cell.get_width()).unwrap_or(0)
- }
-
- /// Get the cell at index `idx`
- pub fn get_cell(&self, idx: usize) -> Option<&Cell> {
- self.cells.get(idx)
- }
-
- /// Get the mutable cell at index `idx`
- pub fn get_mut_cell(&mut self, idx: usize) -> Option<&mut Cell> {
- self.cells.get_mut(idx)
- }
-
- /// Set the `cell` in the row at the given `column`
- pub fn set_cell(&mut self, cell: Cell, column: usize) -> Result<(), &str> {
- if column >= self.len() {
- return Err("Cannot find cell");
- }
- self.cells[column] = cell;
- Ok(())
- }
-
- /// Append a `cell` at the end of the row
- pub fn add_cell(&mut self, cell: Cell) {
- self.cells.push(cell);
- }
-
- /// Insert `cell` at position `index`. If `index` is higher than the row length,
- /// the cell will be appended at the end
- pub fn insert_cell(&mut self, index: usize, cell: Cell) {
- if index < self.cells.len() {
- self.cells.insert(index, cell);
- } else {
- self.add_cell(cell);
- }
- }
-
- /// Remove the cell at position `index`. Silently skip if this cell does not exist
- pub fn remove_cell(&mut self, index: usize) {
- if index < self.cells.len() {
- self.cells.remove(index);
- }
- }
-
- /// Returns an immutable iterator over cells
- pub fn iter<'a>(&'a self) -> Iter<'a, Cell> {
- self.cells.iter()
- }
-
- /// Returns an mutable iterator over cells
- pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Cell> {
- self.cells.iter_mut()
- }
-
- /// Internal only
- fn __print<T:Write+?Sized, F>(&self, out: &mut T, format: &TableFormat, col_width: &[usize], f: F) -> Result<(), Error>
- where F: Fn(&Cell, &mut T, usize, usize, bool) -> Result<(), Error>
- {
- for i in 0..self.get_height() {
- 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]));
- let skip_r_fill = (j == col_width.len() - 1) && format.get_column_separator(ColumnPosition::Right).is_none();
+//! This module contains definition of table rows stuff
+use std::io::{Write, Error};
+use std::iter::FromIterator;
+use std::slice::{Iter, IterMut};
+use std::ops::{Index, IndexMut};
+
+use term::Terminal;
+
+use super::utils::NEWLINE;
+use super::cell::Cell;
+use super::format::{TableFormat, ColumnPosition};
+
+/// Represent a table row made of cells
+#[derive(Clone, Debug)]
+pub struct Row {
+ cells: Vec<Cell>,
+}
+
+impl Row {
+ /// Create a new `Row` backed with `cells` vector
+ pub fn new(cells: Vec<Cell>) -> Row {
+ Row { cells: cells }
+ }
+
+ /// Create an row of length `size`, with empty strings stored
+ pub fn empty() -> Row {
+ Self::new(vec![Cell::default(); 0])
+ }
+
+ /// Get the number of cells in this row
+ pub fn len(&self) -> usize {
+ self.cells.len()
+ }
+
+ /// 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
+ for cell in &self.cells {
+ let h = cell.get_height();
+ if h > height {
+ height = h;
+ }
+ }
+ height
+ }
+
+ /// Get the minimum width required by the cell in the column `column`.
+ /// Return 0 if the cell does not exist in this row
+ pub fn get_cell_width(&self, column: usize) -> usize {
+ self.cells
+ .get(column)
+ .map(|cell| cell.get_width())
+ .unwrap_or(0)
+ }
+
+ /// Get the cell at index `idx`
+ pub fn get_cell(&self, idx: usize) -> Option<&Cell> {
+ self.cells.get(idx)
+ }
+
+ /// Get the mutable cell at index `idx`
+ pub fn get_mut_cell(&mut self, idx: usize) -> Option<&mut Cell> {
+ self.cells.get_mut(idx)
+ }
+
+ /// Set the `cell` in the row at the given `column`
+ pub fn set_cell(&mut self, cell: Cell, column: usize) -> Result<(), &str> {
+ if column >= self.len() {
+ return Err("Cannot find cell");
+ }
+ self.cells[column] = cell;
+ Ok(())
+ }
+
+ /// Append a `cell` at the end of the row
+ pub fn add_cell(&mut self, cell: Cell) {
+ self.cells.push(cell);
+ }
+
+ /// Insert `cell` at position `index`. If `index` is higher than the row length,
+ /// the cell will be appended at the end
+ pub fn insert_cell(&mut self, index: usize, cell: Cell) {
+ if index < self.cells.len() {
+ self.cells.insert(index, cell);
+ } else {
+ self.add_cell(cell);
+ }
+ }
+
+ /// Remove the cell at position `index`. Silently skip if this cell does not exist
+ pub fn remove_cell(&mut self, index: usize) {
+ if index < self.cells.len() {
+ self.cells.remove(index);
+ }
+ }
+
+ /// Returns an immutable iterator over cells
+ pub fn iter<'a>(&'a self) -> Iter<'a, Cell> {
+ self.cells.iter()
+ }
+
+ /// Returns an mutable iterator over cells
+ pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Cell> {
+ self.cells.iter_mut()
+ }
+
+ /// Internal only
+ fn __print<T: Write + ?Sized, F>(&self,
+ out: &mut T,
+ format: &TableFormat,
+ col_width: &[usize],
+ f: F)
+ -> Result<(), Error>
+ where F: Fn(&Cell, &mut T, usize, usize, bool) -> Result<(), Error>
+ {
+ for i in 0..self.get_height() {
+ 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]));
+ 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))
- };
- try!(out.write(&vec![' ' as u8; rp]));
- if j < col_width.len() - 1 {
- try!(format.print_column_separator(out, ColumnPosition::Intern));
- }
- }
- try!(format.print_column_separator(out, ColumnPosition::Right));
- try!(out.write_all(NEWLINE));
- }
- Ok(())
- }
-
- /// Print the row to `out`, with `separator` as column separator, and `col_width`
- /// specifying the width of each columns
- pub fn print<T: Write+?Sized>(&self, out: &mut T, format: &TableFormat, col_width: &[usize]) -> Result<(), Error> {
- self.__print(out, format, col_width, Cell::print)
- }
-
- /// Print the row to terminal `out`, with `separator` as column separator, and `col_width`
- /// specifying the width of each columns. Apply style when needed
- pub fn print_term<T: Terminal+?Sized>(&self, out: &mut T, format: &TableFormat, col_width: &[usize]) -> Result<(), Error> {
- self.__print(out, format, col_width, Cell::print_term)
- }
-}
-
-impl Default for Row {
- fn default() -> Row {
- Row::empty()
- }
-}
-
-impl Index<usize> for Row {
- type Output = Cell;
- fn index(&self, idx: usize) -> &Self::Output {
- &self.cells[idx]
- }
-}
-
-impl IndexMut<usize> for Row {
- fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
- &mut self.cells[idx]
- }
-}
-
-impl <A: ToString> FromIterator<A> for Row {
- fn from_iter<T>(iterator: T) -> Row where T: IntoIterator<Item=A> {
- Self::new(iterator.into_iter().map(|ref e| Cell::from(e)).collect())
- }
-}
-
-impl <T, A> From<T> for Row where A: ToString, T : IntoIterator<Item=A> {
- fn from(it: T) -> Row {
- Self::from_iter(it)
- }
-}
-
-impl <'a> IntoIterator for &'a Row {
- type Item=&'a Cell;
- type IntoIter=Iter<'a, Cell>;
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
- }
-}
-
-impl <'a> IntoIterator for &'a mut Row {
- type Item=&'a mut Cell;
- type IntoIter=IterMut<'a, Cell>;
- fn into_iter(self) -> Self::IntoIter {
- self.iter_mut()
- }
-}
-
-/// This macro simplifies `Row` creation
-///
-/// The syntax support style spec
-/// # Example
-/// ```
-/// # #[macro_use] extern crate prettytable;
-/// # fn main() {
-/// // Create a normal row
-/// let row1 = row!["Element 1", "Element 2", "Element 3"];
-/// // Create a row with all cells formatted with red foreground color, yellow background color
-/// // bold, italic, align in the center of the cell
-/// let row2 = row![FrBybic => "Element 1", "Element 2", "Element 3"];
-/// // Create a row with first cell in blue, second one in red, and last one with default style
-/// let row3 = row![Fb->"blue", Fr->"red", "normal"];
-/// // Do something with rows
-/// # drop(row1);
-/// # drop(row2);
-/// # drop(row3);
-/// # }
-/// ```
-///
-/// For details about style specifier syntax, check doc for [Cell::style_spec](cell/struct.Cell.html#method.style_spec) method
-#[macro_export]
+ None => try!(f(&Cell::default(), out, i, col_width[j], skip_r_fill)),
+ };
+ try!(out.write(&vec![' ' as u8; rp]));
+ if j < col_width.len() - 1 {
+ try!(format.print_column_separator(out, ColumnPosition::Intern));
+ }
+ }
+ try!(format.print_column_separator(out, ColumnPosition::Right));
+ try!(out.write_all(NEWLINE));
+ }
+ Ok(())
+ }
+
+ /// Print the row to `out`, with `separator` as column separator, and `col_width`
+ /// specifying the width of each columns
+ pub fn print<T: Write + ?Sized>(&self,
+ out: &mut T,
+ format: &TableFormat,
+ col_width: &[usize])
+ -> Result<(), Error> {
+ self.__print(out, format, col_width, Cell::print)
+ }
+
+ /// Print the row to terminal `out`, with `separator` as column separator, and `col_width`
+ /// specifying the width of each columns. Apply style when needed
+ pub fn print_term<T: Terminal + ?Sized>(&self,
+ out: &mut T,
+ format: &TableFormat,
+ col_width: &[usize])
+ -> Result<(), Error> {
+ self.__print(out, format, col_width, Cell::print_term)
+ }
+}
+
+impl Default for Row {
+ fn default() -> Row {
+ Row::empty()
+ }
+}
+
+impl Index<usize> for Row {
+ type Output = Cell;
+ fn index(&self, idx: usize) -> &Self::Output {
+ &self.cells[idx]
+ }
+}
+
+impl IndexMut<usize> for Row {
+ fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
+ &mut self.cells[idx]
+ }
+}
+
+impl<A: ToString> FromIterator<A> for Row {
+ fn from_iter<T>(iterator: T) -> Row
+ where T: IntoIterator<Item = A>
+ {
+ Self::new(iterator.into_iter().map(|ref e| Cell::from(e)).collect())
+ }
+}
+
+impl<T, A> From<T> for Row
+ where A: ToString,
+ T: IntoIterator<Item = A>
+{
+ fn from(it: T) -> Row {
+ Self::from_iter(it)
+ }
+}
+
+impl<'a> IntoIterator for &'a Row {
+ type Item = &'a Cell;
+ type IntoIter = Iter<'a, Cell>;
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+impl<'a> IntoIterator for &'a mut Row {
+ type Item = &'a mut Cell;
+ type IntoIter = IterMut<'a, Cell>;
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter_mut()
+ }
+}
+
+/// This macro simplifies `Row` creation
+///
+/// The syntax support style spec
+/// # Example
+/// ```
+/// # #[macro_use] extern crate prettytable;
+/// # fn main() {
+/// // Create a normal row
+/// let row1 = row!["Element 1", "Element 2", "Element 3"];
+/// // Create a row with all cells formatted with red foreground color, yellow background color
+/// // bold, italic, align in the center of the cell
+/// let row2 = row![FrBybic => "Element 1", "Element 2", "Element 3"];
+/// // Create a row with first cell in blue, second one in red, and last one with default style
+/// let row3 = row![Fb->"blue", Fr->"red", "normal"];
+/// // Do something with rows
+/// # drop(row1);
+/// # drop(row2);
+/// # drop(row3);
+/// # }
+/// ```
+///
+/// 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)*));
@@ -220,4 +240,4 @@ macro_rules! row {
($($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)*)));
-}
+}