mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-24 12:51:31 +00:00
166 lines
4.5 KiB
Rust
166 lines
4.5 KiB
Rust
//! This example can be run with the following command:
|
|
//!
|
|
//! `cargo run --example shadow -- "Some text" "In the box"`
|
|
//!
|
|
//! 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::iter::FromIterator;
|
|
|
|
use tabled::{
|
|
builder::Builder,
|
|
grid::{config::Borders, util::string},
|
|
row,
|
|
settings::{
|
|
style::{LineChar, Style},
|
|
Height, 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 args = std::env::args().collect::<Vec<_>>();
|
|
|
|
if args.len() < 2 {
|
|
eprintln!("Expected to get at least 1 argument to be printed");
|
|
std::process::exit(-1);
|
|
}
|
|
|
|
let mut buf = String::new();
|
|
for (i, text) in args.iter().skip(1).enumerate() {
|
|
if i > 0 {
|
|
buf.push('\n');
|
|
}
|
|
|
|
buf.push_str(text);
|
|
}
|
|
|
|
buf
|
|
}
|
|
|
|
fn create_small_table_list(width_available: usize) -> String {
|
|
let style1 = Style::modern();
|
|
let style2 = Style::extended();
|
|
let style3 = Style::modern()
|
|
.left('║')
|
|
.right('║')
|
|
.intersection_left('╟')
|
|
.intersection_right('╢')
|
|
.corner_top_right('╖')
|
|
.corner_top_left('╓')
|
|
.corner_bottom_right('╜')
|
|
.corner_bottom_left('╙');
|
|
let style4 = 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('╪');
|
|
|
|
let mut tables = [
|
|
create_small_table(Borders::from(style1)),
|
|
create_small_table(Borders::from(style2)),
|
|
create_small_table(Borders::from(style3)),
|
|
create_small_table(Borders::from(style4)),
|
|
];
|
|
|
|
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: Borders<char>) -> Table {
|
|
let mut table = Builder::from_iter(vec![vec![" ", ""], vec![" ", ""]]).build();
|
|
table
|
|
.with(style)
|
|
.with(Padding::zero())
|
|
.with(Height::list([1, 0]));
|
|
|
|
table
|
|
}
|
|
|
|
// todo: very likely can be simplified
|
|
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_space = (0..count_additional_separators)
|
|
.map(|_| " ║ \n")
|
|
.collect::<String>();
|
|
|
|
let left_table = format!(
|
|
" ╔═══╗ \n ╚═╦═╝ \n{}═╤══╩══╤\n ├──┬──┤\n └──┴──┘",
|
|
left_table_space
|
|
);
|
|
|
|
let mut message = message.to_owned();
|
|
if count_lines < 2 {
|
|
let mut i = count_lines;
|
|
while i < 2 {
|
|
message.push('\n');
|
|
i += 1;
|
|
}
|
|
}
|
|
|
|
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())
|
|
.modify((0, 0), LineChar::vertical('╞', count_lines))
|
|
.modify((0, 2), LineChar::vertical('╡', count_lines))
|
|
.with(Shadow::new(2));
|
|
|
|
table
|
|
}
|