//! This example demonstrates using the [`Padding::colorize()`] function in several ways //! to give a [`Table`] display a vibrant asthetic. //! //! * 🚩 This example requires the `color` feature. //! //! * Note how the [`Color`] [setting](tabled::settings) is used to simplify creating //! reusable themes for text, backgrounds, padded whitespace, and borders. //! //! * Note how a unique color can be set for each direction. use std::convert::TryFrom; use owo_colors::OwoColorize; use tabled::{ grid::{ config::{ColoredConfig, Entity}, dimension::SpannedGridDimension, records::{ vec_records::{Cell, VecRecords}, ExactRecords, PeekableRecords, Records, }, util::string::string_width_multiline, }, settings::{ object::{Columns, Object, Rows, Segment}, Alignment, CellOption, Color, Format, Margin, Modify, Padding, Style, }, Table, Tabled, }; #[derive(Tabled)] #[tabled(rename_all = "PascalCase")] struct Fundamental { quantity: &'static str, symbol: &'static str, value: &'static str, unit: &'static str, } impl Fundamental { fn new( quantity: &'static str, symbol: &'static str, value: &'static str, unit: &'static str, ) -> Self { Self { quantity, symbol, value, unit, } } } fn main() { // data source: https://www.britannica.com/science/physical-constant let data = [ Fundamental::new( "constant of gravitation", "G", "6.67384 × 10⁻¹¹", "cubic metre per second squared per kilogram", ), Fundamental::new( "speed of light (in a vacuum)", "c", "2.99792458 × 10⁻⁸", "metres per second", ), Fundamental::new( "Planck's constant", "h", "6.626070040 × 10⁻³⁴", "joule second", ), Fundamental::new( "Boltzmann constant", "k", "1.38064852 × 10⁻²³", "joule per kelvin", ), Fundamental::new( "Faraday constant", "F", "9.648533289 × 10⁴", "coulombs per mole", ), ]; let pane_color = Color::try_from(' '.bg_rgb::<220, 220, 220>().to_string()).unwrap(); let border_color = Color::try_from(' '.bg_rgb::<200, 200, 220>().bold().to_string()).unwrap(); let data_color = Color::try_from(' '.bg_rgb::<200, 200, 220>().to_string()).unwrap(); let header_settings = Modify::new(Rows::first()) .with(Padding::new(1, 1, 2, 2).colorize( Color::BG_GREEN, Color::BG_YELLOW, Color::BG_MAGENTA, Color::BG_CYAN, )) .with(MakeMaxPadding) .with(Format::content(|s| s.on_black().white().to_string())); let data_settings = Modify::new(Rows::first().inverse()) .with(Alignment::left()) .with(MakeMaxPadding) .with(Padding::new(1, 1, 0, 0).colorize( Color::default(), Color::default(), data_color.clone(), data_color.clone(), )); let symbol_settings = Modify::new(Columns::single(1).not(Rows::first())) .with(Format::content(|s| s.bold().to_string())); let unit_settings = Modify::new(Columns::single(3).not(Rows::first())) .with(Format::content(|s| s.italic().to_string())); let table = Table::new(data) .with(Style::rounded()) .with(Margin::new(1, 2, 1, 1).colorize( pane_color.clone(), pane_color.clone(), pane_color.clone(), pane_color, )) .with(border_color) .with(Modify::new(Segment::all()).with(data_color)) .with(header_settings) .with(data_settings) .with(symbol_settings) .with(unit_settings) .to_string(); println!("\n\n{table}\n\n"); } #[derive(Debug, Clone)] struct MakeMaxPadding; impl CellOption, ColoredConfig> for MakeMaxPadding where T: Cell + AsRef, { fn change(self, records: &mut VecRecords, cfg: &mut ColoredConfig, entity: Entity) { let widths = SpannedGridDimension::width(&*records, cfg); let count_rows = records.count_rows(); let count_cols = records.count_columns(); for (row, col) in entity.iter(count_rows, count_cols) { let column_width = widths[col]; let text = records.get_text((row, col)); let width = string_width_multiline(text); if width < column_width { let available_width = column_width - width; let left = available_width / 2; let right = available_width - left; let pos = (row, col).into(); let mut pad = cfg.get_padding(pos); pad.left.size = left; pad.right.size = right; cfg.set_padding(pos, pad); } } } }