comfy-table 0.0.7

An easy to use library for building beautiful tables with automatic content wrapping
Documentation
use ::crossterm::style::{Attribute, Color};

use crate::style::CellAlignment;

/// A stylable table cell with content.
#[derive(Clone, Debug)]
pub struct Cell {
    /// Content is a list of strings.
    /// This is done to handle newlines more easily.
    /// On set_content, the incoming string is split by '\n'
    pub(crate) content: Vec<String>,
    pub(crate) alignment: Option<CellAlignment>,
    pub(crate) fg: Option<Color>,
    pub(crate) bg: Option<Color>,
    pub(crate) attributes: Vec<Attribute>,
}

impl Cell {
    /// Create a new Cell
    pub fn new<T: ToString>(content: T) -> Self {
        Cell {
            content: content
                .to_string()
                .split('\n')
                .map(|content| content.to_string())
                .collect(),
            alignment: None,
            fg: None,
            bg: None,
            attributes: Vec::new(),
        }
    }

    /// Return a copy of the content contained in this cell.
    pub fn get_content(&self) -> String {
        return self.content.join("\n").clone();
    }

    /// Set the alignment of content for this cell.
    ///
    /// Setting this overwrites alignment settings of the Column for this specific Cell.
    /// ```
    /// use comfy_table::CellAlignment;
    /// use comfy_table::Cell;
    ///
    /// let mut cell = Cell::new("Some content")
    ///     .set_alignment(CellAlignment::Center);
    /// ```
    pub fn set_alignment(mut self, alignment: CellAlignment) -> Self {
        self.alignment = Some(alignment);

        self
    }

    /// Set the foreground text color for this cell.
    /// comfy-table uses [Crossterm Colors](crossterm::style::Color).
    /// Look at their documentation for all possible Colors.
    /// ```
    /// use comfy_table::Color;
    /// use comfy_table::Cell;
    ///
    /// let mut cell = Cell::new("Some content")
    ///     .fg(Color::Red);
    /// ```
    pub fn fg(mut self, color: Color) -> Self {
        self.fg = Some(color);

        self
    }

    /// Set the background color for this cell.
    /// comfy-table uses [Crossterm Colors](crossterm::style::Color).
    /// Look at their documentation for all possible Colors.
    /// ```
    /// use comfy_table::Color;
    /// use comfy_table::Cell;
    ///
    /// let mut cell = Cell::new("Some content")
    ///     .bg(Color::Red);
    /// ```
    pub fn bg(mut self, color: Color) -> Self {
        self.bg = Some(color);

        self
    }

    /// Add a styling attribute to the content cell
    /// Those can be **bold**, _italic_, blinking and many more.
    /// comfy-table uses [Crossterm Attributes](crossterm::style::Attribute).
    /// Look at their documentation for all possible Attributes.
    /// ```
    /// use comfy_table::Attribute;
    /// use comfy_table::Cell;
    ///
    /// let mut cell = Cell::new("Some content")
    ///     .add_attribute(Attribute::Bold);
    /// ```
    pub fn add_attribute(mut self, attribute: Attribute) -> Self {
        self.attributes.push(attribute);

        self
    }

    /// Same as add_attribute, but you can pass a Vector of Attributes
    pub fn add_attributes(mut self, mut attribute: Vec<Attribute>) -> Self {
        self.attributes.append(&mut attribute);

        self
    }
}

/// Allow the conversion of a type to a vector of cells.
/// By default this is implemented for all types implementing
/// IntoIterator where the iterated Item type implements ToString.
/// E.g. a Vec<i32> works
pub trait ToCells {
    fn to_cells(self) -> Vec<Cell>;
}

impl<T: IntoIterator> ToCells for T
where
    T::Item: ToCell,
{
    fn to_cells(self) -> Vec<Cell> {
        self.into_iter().map(|item| item.to_cell()).collect()
    }
}

pub trait ToCell {
    fn to_cell(self) -> Cell;
}

impl<T: ToString> ToCell for T {
    fn to_cell(self) -> Cell {
        Cell::new(self.to_string())
    }
}

impl ToCell for Cell {
    fn to_cell(self) -> Cell {
        self
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_column_generation() {
        let content = "This is\nsome multiline\nstring".to_string();
        let cell = Cell::new(content.clone());

        assert_eq!(cell.get_content(), content);
    }
}