//! Toolbox for building responsive tables. //! A table is composed of rows, a row is composed of cells. //! The toolbox uses the [builder design pattern]. //! //! [builder design pattern]: https://refactoring.guru/design-patterns/builder use log::trace; use std::fmt; use terminal_size; use unicode_width::UnicodeWidthStr; /// Define the default terminal size. /// It is used when the size cannot be determined by the `terminal_size` crate. const DEFAULT_TERM_WIDTH: usize = 80; /// Define the minimum size of a shrinked cell. /// TODO: make this customizable. const MAX_SHRINK_WIDTH: usize = 5; /// Wrapper around [ANSI escape codes] for styling cells. /// /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code #[derive(Debug)] pub struct Style( /// The style/color code. u8, /// The brightness code. u8, /// The shade code. u8, ); impl fmt::Display for Style { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Style(color, bright, shade) = self; let mut style = String::new(); // Push first the style/color code. style.push_str(&color.to_string()); // Then push the brightness code if exist. if *bright > 0 { style.push_str(";"); style.push_str(&bright.to_string()); }; // Then push the shade code if exist. if *shade > 0 { style.push_str(";"); style.push_str(&shade.to_string()); }; write!(f, "\x1b[{}m", style) } } /// Representation of a table cell. #[derive(Debug)] pub struct Cell { /// The list of style applied to the cell. styles: Vec