| //! This example can be run with the following command: |
| //! |
| //! `echo -e -n 'Some text\nIn the box' | cargo run --example shadow` |
| //! |
| //! This example demonstrates using the [`Shadow`] [`TableOption`] to create |
| //! a striking frame around a [`Table`] display. |
| //! |
| //! * [`Shadow`] supports several configurations: |
| //! * Thickness |
| //! * Offset |
| //! * Direction |
| //! * Color |
| //! * Fill character |
| //! |
| //! * 🎉 Inspired by <https://en.wikipedia.org/wiki/Box-drawing_character> |
| |
| use std::{io::Read, iter::FromIterator}; |
| |
| use tabled::{ |
| builder::Builder, |
| grid::util::string, |
| row, |
| settings::{ |
| object::Cell, |
| style::{BorderChar, Offset, RawStyle, Style}, |
| Height, Modify, Padding, Shadow, Width, |
| }, |
| Table, |
| }; |
| |
| fn main() { |
| let message = read_message(); |
| print_table(message); |
| } |
| |
| fn print_table(message: String) { |
| let main_table = create_main_table(&message); |
| let main_table_width = main_table.total_width(); |
| let small_table_row = create_small_table_list(main_table_width); |
| println!("{small_table_row}"); |
| println!("{main_table}"); |
| } |
| |
| fn read_message() -> String { |
| let mut buf = String::new(); |
| std::io::stdin().read_to_string(&mut buf).unwrap(); |
| |
| buf |
| } |
| |
| fn create_small_table_list(width_available: usize) -> String { |
| let mut tables = [ |
| create_small_table(Style::modern().into()), |
| create_small_table(Style::extended().into()), |
| create_small_table( |
| Style::modern() |
| .left('║') |
| .right('║') |
| .intersection_left('╟') |
| .intersection_right('╢') |
| .corner_top_right('╖') |
| .corner_top_left('╓') |
| .corner_bottom_right('╜') |
| .corner_bottom_left('╙') |
| .into(), |
| ), |
| create_small_table( |
| Style::modern() |
| .top('═') |
| .bottom('═') |
| .corner_top_right('╕') |
| .corner_top_left('╒') |
| .corner_bottom_right('╛') |
| .corner_bottom_left('╘') |
| .horizontal('═') |
| .intersection_left('╞') |
| .intersection_right('╡') |
| .intersection_top('╤') |
| .intersection_bottom('╧') |
| .intersection('╪') |
| .into(), |
| ), |
| ]; |
| const TOTAL_TABLE_WIDTH: usize = 19; |
| |
| if width_available > TOTAL_TABLE_WIDTH { |
| let mut rest = width_available - TOTAL_TABLE_WIDTH; |
| while rest > 0 { |
| for table in &mut tables { |
| let current_width = table.total_width(); |
| table.with(Width::increase(current_width + 1)); |
| rest -= 1; |
| |
| if rest == 0 { |
| break; |
| } |
| } |
| } |
| } |
| |
| let small_table_row = row![tables[0], tables[1], tables[2], tables[3]] |
| .with(Style::blank()) |
| .with(Padding::zero()) |
| .to_string(); |
| small_table_row |
| } |
| |
| fn create_small_table(style: RawStyle) -> Table { |
| let mut table = Builder::from_iter(vec![vec![" ", ""], vec![" ", ""]]).build(); |
| table |
| .with(style) |
| .with(Padding::zero()) |
| .with(Height::list([1, 0])); |
| |
| table |
| } |
| |
| fn create_main_table(message: &str) -> Table { |
| let (count_lines, message_width) = string::string_dimension(message); |
| let count_additional_separators = if count_lines > 2 { count_lines - 2 } else { 0 }; |
| |
| let left_table = format!( |
| " ╔═══╗ \n ╚═╦═╝ \n{}═╤══╩══╤\n ├──┬──┤\n └──┴──┘", |
| (0..count_additional_separators) |
| .map(|_| " ║ \n") |
| .collect::<String>() |
| ); |
| |
| let message = if count_lines < 2 { |
| let mut i = count_lines; |
| let mut buf = message.to_string(); |
| while i < 2 { |
| buf.push('\n'); |
| i += 1; |
| } |
| |
| buf |
| } else { |
| message.to_owned() |
| }; |
| let count_lines = count_lines.max(2); |
| |
| let message = format!("{}\n{}", message, "═".repeat(message_width)); |
| |
| let mut table = row![left_table, message]; |
| table |
| .with(Padding::zero()) |
| .with(Style::modern().remove_vertical()) |
| .with( |
| Modify::new(Cell::new(0, 0)) |
| .with(BorderChar::vertical('╞', Offset::Begin(count_lines))), |
| ) |
| .with( |
| Modify::new(Cell::new(0, 2)) |
| .with(BorderChar::vertical('╡', Offset::Begin(count_lines))), |
| ) |
| .with(Shadow::new(2)); |
| |
| table |
| } |