mirror of
https://github.com/nushell/nushell
synced 2025-01-13 13:49:21 +00:00
Refactroings
This commit is contained in:
parent
25a5fca41d
commit
91130104f8
13 changed files with 301 additions and 273 deletions
|
@ -18,8 +18,8 @@ use nu_protocol::{
|
||||||
ByteStream, Config, DataSource, ListStream, PipelineMetadata, Signals, TableMode, ValueIterator,
|
ByteStream, Config, DataSource, ListStream, PipelineMetadata, Signals, TableMode, ValueIterator,
|
||||||
};
|
};
|
||||||
use nu_table::{
|
use nu_table::{
|
||||||
common::create_nu_table_config, CollapsedTable, ExpandedTable, JustTable, NuRecordsValue,
|
common::configure_table, CollapsedTable, ExpandedTable, JustTable, NuRecordsValue, NuTable,
|
||||||
NuTable, StringResult, TableOpts, TableOutput,
|
StringResult, TableOpts, TableOutput,
|
||||||
};
|
};
|
||||||
use nu_utils::{get_ls_colors, terminal_size};
|
use nu_utils::{get_ls_colors, terminal_size};
|
||||||
|
|
||||||
|
@ -1070,13 +1070,13 @@ fn create_empty_placeholder(
|
||||||
let data = vec![vec![cell]];
|
let data = vec![vec![cell]];
|
||||||
let mut table = NuTable::from(data);
|
let mut table = NuTable::from(data);
|
||||||
table.set_data_style(TextStyle::default().dimmed());
|
table.set_data_style(TextStyle::default().dimmed());
|
||||||
let out = TableOutput::from_table(table, false, false);
|
let mut out = TableOutput::from_table(table, false, false);
|
||||||
|
|
||||||
let style_computer = &StyleComputer::from_config(engine_state, stack);
|
let style_computer = &StyleComputer::from_config(engine_state, stack);
|
||||||
let config = create_nu_table_config(&config, style_computer, &out, false, TableMode::default());
|
configure_table(&mut out, &config, style_computer, TableMode::default());
|
||||||
|
|
||||||
out.table
|
out.table
|
||||||
.draw(config, termwidth)
|
.draw(termwidth)
|
||||||
.expect("Could not create empty table placeholder")
|
.expect("Could not create empty table placeholder")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use nu_ansi_term::{Color, Style};
|
use nu_ansi_term::{Color, Style};
|
||||||
use nu_color_config::TextStyle;
|
use nu_color_config::TextStyle;
|
||||||
use nu_table::{NuTable, NuTableConfig, TableTheme};
|
use nu_table::{NuTable, TableTheme};
|
||||||
use tabled::grid::records::vec_records::Text;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -28,15 +28,11 @@ fn main() {
|
||||||
|
|
||||||
table.set_data_style(TextStyle::basic_left());
|
table.set_data_style(TextStyle::basic_left());
|
||||||
table.set_header_style(TextStyle::basic_center().style(Style::new().on(Color::Blue)));
|
table.set_header_style(TextStyle::basic_center().style(Style::new().on(Color::Blue)));
|
||||||
|
table.set_theme(TableTheme::rounded());
|
||||||
let table_cfg = NuTableConfig {
|
table.set_structure(false, true, false);
|
||||||
theme: TableTheme::rounded(),
|
|
||||||
with_header: true,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let output_table = table
|
let output_table = table
|
||||||
.draw(table_cfg, width)
|
.draw(width)
|
||||||
.unwrap_or_else(|| format!("Couldn't fit table into {width} columns!"));
|
.unwrap_or_else(|| format!("Couldn't fit table into {width} columns!"));
|
||||||
|
|
||||||
println!("{output_table}")
|
println!("{output_table}")
|
||||||
|
|
|
@ -3,9 +3,7 @@ use nu_protocol::{Config, FooterMode, ShellError, Span, TableMode, TrimStrategy,
|
||||||
|
|
||||||
use terminal_size::{terminal_size, Height, Width};
|
use terminal_size::{terminal_size, Height, Width};
|
||||||
|
|
||||||
use crate::{
|
use crate::{clean_charset, colorize_space_str, string_wrap, TableOutput, TableTheme};
|
||||||
clean_charset, colorize_space_str, string_wrap, NuTableConfig, TableOutput, TableTheme,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type NuText = (String, TextStyle);
|
pub type NuText = (String, TextStyle);
|
||||||
pub type TableResult = Result<Option<TableOutput>, ShellError>;
|
pub type TableResult = Result<Option<TableOutput>, ShellError>;
|
||||||
|
@ -13,30 +11,31 @@ pub type StringResult = Result<Option<String>, ShellError>;
|
||||||
|
|
||||||
pub const INDEX_COLUMN_NAME: &str = "index";
|
pub const INDEX_COLUMN_NAME: &str = "index";
|
||||||
|
|
||||||
pub fn create_nu_table_config(
|
pub fn configure_table(
|
||||||
|
out: &mut TableOutput,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
comp: &StyleComputer,
|
comp: &StyleComputer,
|
||||||
out: &TableOutput,
|
|
||||||
expand: bool,
|
|
||||||
mode: TableMode,
|
mode: TableMode,
|
||||||
) -> NuTableConfig {
|
) {
|
||||||
|
let with_footer = is_footer_needed(config, out);
|
||||||
|
let theme = load_theme(mode);
|
||||||
|
|
||||||
|
out.table.set_theme(theme);
|
||||||
|
out.table
|
||||||
|
.set_structure(out.with_index, out.with_header, with_footer);
|
||||||
|
out.table.set_trim(config.table.trim.clone());
|
||||||
|
out.table
|
||||||
|
.set_border_header(config.table.header_on_separator);
|
||||||
|
out.table.set_border_color(lookup_separator_color(comp));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_footer_needed(config: &Config, out: &TableOutput) -> bool {
|
||||||
let mut count_rows = out.table.count_rows();
|
let mut count_rows = out.table.count_rows();
|
||||||
if config.table.footer_inheritance {
|
if config.table.footer_inheritance {
|
||||||
count_rows = out.count_rows;
|
count_rows = out.count_rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
let with_footer = with_footer(config, out.with_header, count_rows);
|
with_footer(config, out.with_header, count_rows)
|
||||||
|
|
||||||
NuTableConfig {
|
|
||||||
theme: load_theme(mode),
|
|
||||||
with_footer,
|
|
||||||
with_index: out.with_index,
|
|
||||||
with_header: out.with_header,
|
|
||||||
split_color: Some(lookup_separator_color(comp)),
|
|
||||||
trim: config.table.trim.clone(),
|
|
||||||
header_on_border: config.table.header_on_separator,
|
|
||||||
expand,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nu_value_to_string_colored(val: &Value, cfg: &Config, comp: &StyleComputer) -> String {
|
pub fn nu_value_to_string_colored(val: &Value, cfg: &Config, comp: &StyleComputer) -> String {
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub mod common;
|
||||||
|
|
||||||
pub use common::{StringResult, TableResult};
|
pub use common::{StringResult, TableResult};
|
||||||
pub use nu_color_config::TextStyle;
|
pub use nu_color_config::TextStyle;
|
||||||
pub use table::{NuRecordsValue, NuTable, NuTableConfig};
|
pub use table::{NuRecordsValue, NuTable};
|
||||||
pub use table_theme::TableTheme;
|
pub use table_theme::TableTheme;
|
||||||
pub use types::{CollapsedTable, ExpandedTable, JustTable, TableOpts, TableOutput};
|
pub use types::{CollapsedTable, ExpandedTable, JustTable, TableOpts, TableOutput};
|
||||||
pub use unstructured_table::UnstructuredTable;
|
pub use unstructured_table::UnstructuredTable;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::{cmp::min, collections::HashMap};
|
||||||
|
|
||||||
use nu_ansi_term::Style;
|
use nu_ansi_term::Style;
|
||||||
use nu_color_config::TextStyle;
|
use nu_color_config::TextStyle;
|
||||||
use nu_protocol::TrimStrategy;
|
use nu_protocol::{TableIndent, TrimStrategy};
|
||||||
use nu_utils::strip_ansi_unlikely;
|
use nu_utils::strip_ansi_unlikely;
|
||||||
|
|
||||||
use tabled::{
|
use tabled::{
|
||||||
|
@ -40,29 +40,15 @@ pub struct NuTable {
|
||||||
data: NuRecords,
|
data: NuRecords,
|
||||||
styles: Styles,
|
styles: Styles,
|
||||||
alignments: Alignments,
|
alignments: Alignments,
|
||||||
indent: (usize, usize),
|
config: TableConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
struct TableConfig<Value> {
|
|
||||||
data: Value,
|
|
||||||
index: Value,
|
|
||||||
header: Value,
|
|
||||||
columns: HashMap<usize, Value>,
|
|
||||||
cells: HashMap<Position, Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
type Alignments = TableConfig<AlignmentHorizontal>;
|
|
||||||
|
|
||||||
type Styles = TableConfig<Color>;
|
|
||||||
|
|
||||||
impl NuTable {
|
impl NuTable {
|
||||||
/// Creates an empty [`NuTable`] instance.
|
/// Creates an empty [`NuTable`] instance.
|
||||||
pub fn new(count_rows: usize, count_columns: usize) -> Self {
|
pub fn new(count_rows: usize, count_columns: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data: VecRecords::new(vec![vec![Text::default(); count_columns]; count_rows]),
|
data: VecRecords::new(vec![vec![Text::default(); count_columns]; count_rows]),
|
||||||
styles: Styles::default(),
|
styles: Styles::default(),
|
||||||
indent: (1, 1),
|
|
||||||
alignments: Alignments {
|
alignments: Alignments {
|
||||||
data: AlignmentHorizontal::Left,
|
data: AlignmentHorizontal::Left,
|
||||||
index: AlignmentHorizontal::Right,
|
index: AlignmentHorizontal::Right,
|
||||||
|
@ -70,6 +56,15 @@ impl NuTable {
|
||||||
columns: HashMap::default(),
|
columns: HashMap::default(),
|
||||||
cells: HashMap::default(),
|
cells: HashMap::default(),
|
||||||
},
|
},
|
||||||
|
config: TableConfig {
|
||||||
|
theme: TableTheme::basic(),
|
||||||
|
trim: TrimStrategy::truncate(None),
|
||||||
|
structure: TableStructure::new(false, false, false),
|
||||||
|
indent: TableIndent::new(1, 1),
|
||||||
|
header_on_border: false,
|
||||||
|
expand: false,
|
||||||
|
border_color: None,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,8 +146,32 @@ impl NuTable {
|
||||||
self.alignments.data = convert_alignment(style.alignment);
|
self.alignments.data = convert_alignment(style.alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_indent(&mut self, left: usize, right: usize) {
|
pub fn set_indent(&mut self, indent: TableIndent) {
|
||||||
self.indent = (left, right);
|
self.config.indent = indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_theme(&mut self, theme: TableTheme) {
|
||||||
|
self.config.theme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_structure(&mut self, index: bool, header: bool, footer: bool) {
|
||||||
|
self.config.structure = TableStructure::new(index, header, footer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_border_header(&mut self, on: bool) {
|
||||||
|
self.config.header_on_border = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_trim(&mut self, strategy: TrimStrategy) {
|
||||||
|
self.config.trim = strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_strategy(&mut self, expand: bool) {
|
||||||
|
self.config.expand = expand;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_border_color(&mut self, color: Style) {
|
||||||
|
self.config.border_color = (!color.is_plain()).then_some(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_records_mut(&mut self) -> &mut NuRecords {
|
pub fn get_records_mut(&mut self) -> &mut NuRecords {
|
||||||
|
@ -162,21 +181,15 @@ impl NuTable {
|
||||||
/// Converts a table to a String.
|
/// Converts a table to a String.
|
||||||
///
|
///
|
||||||
/// It returns None in case where table cannot be fit to a terminal width.
|
/// It returns None in case where table cannot be fit to a terminal width.
|
||||||
pub fn draw(self, config: NuTableConfig, termwidth: usize) -> Option<String> {
|
pub fn draw(self, termwidth: usize) -> Option<String> {
|
||||||
build_table(
|
build_table(self, termwidth)
|
||||||
self.data,
|
|
||||||
config,
|
|
||||||
self.alignments,
|
|
||||||
self.styles,
|
|
||||||
termwidth,
|
|
||||||
self.indent,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a total table width.
|
/// Return a total table width.
|
||||||
pub fn total_width(&self, config: &NuTableConfig) -> usize {
|
pub fn total_width(&self) -> usize {
|
||||||
let config = get_config(&config.theme, false, None);
|
let config = create_config(&self.config.theme, false, None);
|
||||||
let widths = build_width(&self.data, self.indent.0 + self.indent.1);
|
let pad = indent_sum(self.config.indent);
|
||||||
|
let widths = build_width(&self.data, pad);
|
||||||
get_total_width2(&widths, &config)
|
get_total_width2(&widths, &config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,33 +203,31 @@ impl From<Vec<Vec<Text<String>>>> for NuTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Alignments = CellConfiguration<AlignmentHorizontal>;
|
||||||
|
|
||||||
|
type Styles = CellConfiguration<Color>;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
struct CellConfiguration<Value> {
|
||||||
|
data: Value,
|
||||||
|
index: Value,
|
||||||
|
header: Value,
|
||||||
|
columns: HashMap<usize, Value>,
|
||||||
|
cells: HashMap<Position, Value>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct NuTableConfig {
|
pub struct TableConfig {
|
||||||
pub theme: TableTheme,
|
theme: TableTheme,
|
||||||
pub trim: TrimStrategy,
|
trim: TrimStrategy,
|
||||||
pub split_color: Option<Style>,
|
border_color: Option<Style>,
|
||||||
pub expand: bool,
|
expand: bool,
|
||||||
pub with_index: bool,
|
structure: TableStructure,
|
||||||
pub with_header: bool,
|
header_on_border: bool,
|
||||||
pub with_footer: bool,
|
indent: TableIndent,
|
||||||
pub header_on_border: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for NuTableConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
theme: TableTheme::basic(),
|
|
||||||
trim: TrimStrategy::truncate(None),
|
|
||||||
with_header: false,
|
|
||||||
with_index: false,
|
|
||||||
with_footer: false,
|
|
||||||
expand: false,
|
|
||||||
split_color: None,
|
|
||||||
header_on_border: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
struct TableStructure {
|
struct TableStructure {
|
||||||
with_index: bool,
|
with_index: bool,
|
||||||
with_header: bool,
|
with_header: bool,
|
||||||
|
@ -233,64 +244,62 @@ impl TableStructure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_table(
|
fn build_table(mut t: NuTable, termwidth: usize) -> Option<String> {
|
||||||
mut data: NuRecords,
|
if t.count_columns() == 0 || t.count_rows() == 0 {
|
||||||
cfg: NuTableConfig,
|
|
||||||
alignments: Alignments,
|
|
||||||
styles: Styles,
|
|
||||||
termwidth: usize,
|
|
||||||
indent: (usize, usize),
|
|
||||||
) -> Option<String> {
|
|
||||||
if data.count_columns() == 0 || data.count_rows() == 0 {
|
|
||||||
return Some(String::new());
|
return Some(String::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
let pad = indent.0 + indent.1;
|
let widths = table_truncate(&mut t, termwidth)?;
|
||||||
let widths = maybe_truncate_columns(&mut data, &cfg, termwidth, pad);
|
table_insert_footer(&mut t);
|
||||||
|
draw_table(t, widths, termwidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table_insert_footer(t: &mut NuTable) {
|
||||||
|
if t.config.structure.with_header && t.config.structure.with_footer {
|
||||||
|
duplicate_row(&mut t.data, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table_truncate(t: &mut NuTable, termwidth: usize) -> Option<Vec<usize>> {
|
||||||
|
let pad = t.config.indent.left + t.config.indent.right;
|
||||||
|
let widths = maybe_truncate_columns(&mut t.data, &t.config, termwidth, pad);
|
||||||
if widths.is_empty() {
|
if widths.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.with_header && cfg.with_footer {
|
Some(widths)
|
||||||
duplicate_row(&mut data, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_table(data, alignments, styles, widths, cfg, termwidth, indent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_table(
|
fn draw_table(t: NuTable, widths: Vec<usize>, termwidth: usize) -> Option<String> {
|
||||||
data: NuRecords,
|
let structure = get_table_structure(&t.data, &t.config);
|
||||||
alignments: Alignments,
|
let sep_color = t.config.border_color;
|
||||||
styles: Styles,
|
let border_header = structure.with_header && t.config.header_on_border;
|
||||||
widths: Vec<usize>,
|
|
||||||
cfg: NuTableConfig,
|
|
||||||
termwidth: usize,
|
|
||||||
indent: (usize, usize),
|
|
||||||
) -> Option<String> {
|
|
||||||
let structure = get_table_structure(&data, &cfg);
|
|
||||||
let sep_color = cfg.split_color;
|
|
||||||
let border_header = structure.with_header && cfg.header_on_border;
|
|
||||||
|
|
||||||
let data: Vec<Vec<_>> = data.into();
|
// TODO: Optimize in tabled
|
||||||
|
let data: Vec<Vec<_>> = t.data.into();
|
||||||
let mut table = Builder::from(data).build();
|
let mut table = Builder::from(data).build();
|
||||||
|
|
||||||
set_indent(&mut table, indent.0, indent.1);
|
set_indent(&mut table, t.config.indent);
|
||||||
load_theme(&mut table, &cfg.theme, &structure, sep_color);
|
load_theme(&mut table, &t.config.theme, &structure, sep_color);
|
||||||
align_table(&mut table, alignments, &structure);
|
align_table(&mut table, t.alignments, &structure);
|
||||||
colorize_table(&mut table, styles, &structure);
|
colorize_table(&mut table, t.styles, &structure);
|
||||||
|
|
||||||
let pad = indent.0 + indent.1;
|
let pad = indent_sum(t.config.indent);
|
||||||
let width_ctrl = WidthCtrl::new(widths, cfg, termwidth, pad);
|
let width_ctrl = WidthCtrl::new(widths, t.config, termwidth, pad);
|
||||||
|
|
||||||
adjust_table(&mut table, width_ctrl, border_header, structure.with_footer);
|
adjust_table(&mut table, width_ctrl, border_header, structure.with_footer);
|
||||||
|
|
||||||
table_to_string(table, termwidth)
|
table_to_string(table, termwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_table_structure(data: &VecRecords<Text<String>>, cfg: &NuTableConfig) -> TableStructure {
|
fn indent_sum(indent: TableIndent) -> usize {
|
||||||
let with_index = cfg.with_index;
|
indent.left + indent.right
|
||||||
let with_header = cfg.with_header && data.count_rows() > 1;
|
}
|
||||||
let with_footer = with_header && cfg.with_footer;
|
|
||||||
|
fn get_table_structure(data: &VecRecords<Text<String>>, cfg: &TableConfig) -> TableStructure {
|
||||||
|
let with_index = cfg.structure.with_index;
|
||||||
|
let with_header = cfg.structure.with_header && data.count_rows() > 1;
|
||||||
|
let with_footer = with_header && cfg.structure.with_footer;
|
||||||
|
|
||||||
TableStructure::new(with_index, with_header, with_footer)
|
TableStructure::new(with_index, with_header, with_footer)
|
||||||
}
|
}
|
||||||
|
@ -307,8 +316,8 @@ fn adjust_table(table: &mut Table, width_ctrl: WidthCtrl, border_header: bool, w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_indent(table: &mut Table, left: usize, right: usize) {
|
fn set_indent(table: &mut Table, indent: TableIndent) {
|
||||||
table.with(Padding::new(left, right, 0, 0));
|
table.with(Padding::new(indent.left, indent.right, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_border_head(table: &mut Table, wctrl: WidthCtrl) {
|
fn set_border_head(table: &mut Table, wctrl: WidthCtrl) {
|
||||||
|
@ -377,13 +386,13 @@ fn table_to_string(table: Table, termwidth: usize) -> Option<String> {
|
||||||
|
|
||||||
struct WidthCtrl {
|
struct WidthCtrl {
|
||||||
width: Vec<usize>,
|
width: Vec<usize>,
|
||||||
cfg: NuTableConfig,
|
cfg: TableConfig,
|
||||||
width_max: usize,
|
width_max: usize,
|
||||||
pad: usize,
|
pad: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidthCtrl {
|
impl WidthCtrl {
|
||||||
fn new(width: Vec<usize>, cfg: NuTableConfig, max: usize, pad: usize) -> Self {
|
fn new(width: Vec<usize>, cfg: TableConfig, max: usize, pad: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
width,
|
width,
|
||||||
cfg,
|
cfg,
|
||||||
|
@ -404,7 +413,7 @@ impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for
|
||||||
|
|
||||||
let need_truncation = total_width > self.width_max;
|
let need_truncation = total_width > self.width_max;
|
||||||
if need_truncation {
|
if need_truncation {
|
||||||
let has_header = self.cfg.with_header && rec.count_rows() > 1;
|
let has_header = self.cfg.structure.with_header && rec.count_rows() > 1;
|
||||||
let as_head = has_header && self.cfg.header_on_border;
|
let as_head = has_header && self.cfg.header_on_border;
|
||||||
|
|
||||||
let trim = TableTrim::new(self.width, self.width_max, self.cfg.trim, as_head, self.pad);
|
let trim = TableTrim::new(self.width, self.width_max, self.cfg.trim, as_head, self.pad);
|
||||||
|
@ -654,14 +663,14 @@ fn load_theme(
|
||||||
|
|
||||||
fn maybe_truncate_columns(
|
fn maybe_truncate_columns(
|
||||||
data: &mut NuRecords,
|
data: &mut NuRecords,
|
||||||
cfg: &NuTableConfig,
|
cfg: &TableConfig,
|
||||||
termwidth: usize,
|
termwidth: usize,
|
||||||
pad: usize,
|
pad: usize,
|
||||||
) -> Vec<usize> {
|
) -> Vec<usize> {
|
||||||
const TERMWIDTH_THRESHOLD: usize = 120;
|
const TERMWIDTH_THRESHOLD: usize = 120;
|
||||||
|
|
||||||
let preserve_content = termwidth > TERMWIDTH_THRESHOLD;
|
let preserve_content = termwidth > TERMWIDTH_THRESHOLD;
|
||||||
let has_header = cfg.with_header && data.count_rows() > 1;
|
let has_header = cfg.structure.with_header && data.count_rows() > 1;
|
||||||
let is_header_on_border = has_header && cfg.header_on_border;
|
let is_header_on_border = has_header && cfg.header_on_border;
|
||||||
|
|
||||||
let truncate = if is_header_on_border {
|
let truncate = if is_header_on_border {
|
||||||
|
@ -685,7 +694,7 @@ fn truncate_columns_by_content(
|
||||||
const MIN_ACCEPTABLE_WIDTH: usize = 3;
|
const MIN_ACCEPTABLE_WIDTH: usize = 3;
|
||||||
const TRAILING_COLUMN_WIDTH: usize = 5;
|
const TRAILING_COLUMN_WIDTH: usize = 5;
|
||||||
|
|
||||||
let config = get_config(theme, false, None);
|
let config = create_config(theme, false, None);
|
||||||
let mut widths = build_width(&*data, pad);
|
let mut widths = build_width(&*data, pad);
|
||||||
let total_width = get_total_width2(&widths, &config);
|
let total_width = get_total_width2(&widths, &config);
|
||||||
if total_width <= termwidth {
|
if total_width <= termwidth {
|
||||||
|
@ -765,7 +774,7 @@ fn truncate_columns_by_columns(
|
||||||
let acceptable_width = 10 + pad;
|
let acceptable_width = 10 + pad;
|
||||||
let trailing_column_width = 3 + pad;
|
let trailing_column_width = 3 + pad;
|
||||||
|
|
||||||
let config = get_config(theme, false, None);
|
let config = create_config(theme, false, None);
|
||||||
let mut widths = build_width(&*data, pad);
|
let mut widths = build_width(&*data, pad);
|
||||||
let total_width = get_total_width2(&widths, &config);
|
let total_width = get_total_width2(&widths, &config);
|
||||||
if total_width <= termwidth {
|
if total_width <= termwidth {
|
||||||
|
@ -836,7 +845,7 @@ fn truncate_columns_by_head(
|
||||||
) -> Vec<usize> {
|
) -> Vec<usize> {
|
||||||
const TRAILING_COLUMN_WIDTH: usize = 5;
|
const TRAILING_COLUMN_WIDTH: usize = 5;
|
||||||
|
|
||||||
let config = get_config(theme, false, None);
|
let config = create_config(theme, false, None);
|
||||||
let mut widths = build_width(&*data, pad);
|
let mut widths = build_width(&*data, pad);
|
||||||
let total_width = get_total_width2(&widths, &config);
|
let total_width = get_total_width2(&widths, &config);
|
||||||
if total_width <= termwidth {
|
if total_width <= termwidth {
|
||||||
|
@ -912,7 +921,7 @@ fn get_total_width2(widths: &[usize], cfg: &ColoredConfig) -> usize {
|
||||||
total + countv + margin.left.size + margin.right.size
|
total + countv + margin.left.size + margin.right.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_config(theme: &TableTheme, with_header: bool, color: Option<Style>) -> ColoredConfig {
|
fn create_config(theme: &TableTheme, with_header: bool, color: Option<Style>) -> ColoredConfig {
|
||||||
let structure = TableStructure::new(false, with_header, false);
|
let structure = TableStructure::new(false, with_header, false);
|
||||||
let mut table = Table::new([[""]]);
|
let mut table = Table::new([[""]]);
|
||||||
load_theme(&mut table, theme, &structure, color);
|
load_theme(&mut table, theme, &structure, color);
|
||||||
|
|
|
@ -8,9 +8,9 @@ use tabled::grid::config::Position;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{
|
common::{
|
||||||
check_value, create_nu_table_config, error_sign, get_header_style, get_index_style,
|
check_value, configure_table, error_sign, get_header_style, get_index_style, load_theme,
|
||||||
load_theme, nu_value_to_string, nu_value_to_string_clean, nu_value_to_string_colored,
|
nu_value_to_string, nu_value_to_string_clean, nu_value_to_string_colored, wrap_text,
|
||||||
wrap_text, NuText, StringResult, TableResult, INDEX_COLUMN_NAME,
|
NuText, StringResult, TableResult, INDEX_COLUMN_NAME,
|
||||||
},
|
},
|
||||||
string_width,
|
string_width,
|
||||||
types::has_index,
|
types::has_index,
|
||||||
|
@ -47,12 +47,19 @@ impl ExpandedTable {
|
||||||
pub fn build_list(self, vals: &[Value], opts: TableOpts<'_>) -> StringResult {
|
pub fn build_list(self, vals: &[Value], opts: TableOpts<'_>) -> StringResult {
|
||||||
let cfg = Cfg { opts, format: self };
|
let cfg = Cfg { opts, format: self };
|
||||||
let output = expand_list(vals, cfg.clone())?;
|
let output = expand_list(vals, cfg.clone())?;
|
||||||
let output = match output {
|
let mut output = match output {
|
||||||
Some(out) => out,
|
Some(out) => out,
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
maybe_expand_table(output, cfg.opts.width, &cfg.opts)
|
configure_table(
|
||||||
|
&mut output,
|
||||||
|
cfg.opts.config,
|
||||||
|
&cfg.opts.style_computer,
|
||||||
|
cfg.opts.mode,
|
||||||
|
);
|
||||||
|
|
||||||
|
maybe_expand_table(output, cfg.opts.width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,10 +207,7 @@ fn expand_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut table = NuTable::from(data);
|
let mut table = NuTable::from(data);
|
||||||
table.set_indent(
|
table.set_indent(cfg.opts.config.table.padding);
|
||||||
cfg.opts.config.table.padding.left,
|
|
||||||
cfg.opts.config.table.padding.right,
|
|
||||||
);
|
|
||||||
table.set_index_style(get_index_style(&cfg.opts.style_computer));
|
table.set_index_style(get_index_style(&cfg.opts.style_computer));
|
||||||
set_data_styles(&mut table, data_styles);
|
set_data_styles(&mut table, data_styles);
|
||||||
|
|
||||||
|
@ -363,10 +367,7 @@ fn expand_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
|
||||||
let mut table = NuTable::from(data);
|
let mut table = NuTable::from(data);
|
||||||
table.set_index_style(get_index_style(&cfg.opts.style_computer));
|
table.set_index_style(get_index_style(&cfg.opts.style_computer));
|
||||||
table.set_header_style(get_header_style(&cfg.opts.style_computer));
|
table.set_header_style(get_header_style(&cfg.opts.style_computer));
|
||||||
table.set_indent(
|
table.set_indent(cfg.opts.config.table.padding);
|
||||||
cfg.opts.config.table.padding.left,
|
|
||||||
cfg.opts.config.table.padding.right,
|
|
||||||
);
|
|
||||||
set_data_styles(&mut table, data_styles);
|
set_data_styles(&mut table, data_styles);
|
||||||
|
|
||||||
Ok(Some(TableOutput::new(table, true, with_index, rows_count)))
|
Ok(Some(TableOutput::new(table, true, with_index, rows_count)))
|
||||||
|
@ -421,14 +422,11 @@ fn expanded_table_kv(record: &Record, cfg: Cfg<'_>) -> CellResult {
|
||||||
|
|
||||||
let mut table = NuTable::from(data);
|
let mut table = NuTable::from(data);
|
||||||
table.set_index_style(get_key_style(&cfg));
|
table.set_index_style(get_key_style(&cfg));
|
||||||
table.set_indent(
|
table.set_indent(cfg.opts.config.table.padding);
|
||||||
cfg.opts.config.table.padding.left,
|
|
||||||
cfg.opts.config.table.padding.right,
|
|
||||||
);
|
|
||||||
|
|
||||||
let out = TableOutput::new(table, false, true, count_rows);
|
let out = TableOutput::new(table, false, true, count_rows);
|
||||||
|
|
||||||
maybe_expand_table(out, cfg.opts.width, &cfg.opts)
|
maybe_expand_table(out, cfg.opts.width)
|
||||||
.map(|value| value.map(|value| CellOutput::clean(value, count_rows, false)))
|
.map(|value| value.map(|value| CellOutput::clean(value, count_rows, false)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,9 +444,9 @@ fn expand_value(value: &Value, width: usize, cfg: &Cfg<'_>) -> CellResult {
|
||||||
let table = expand_list(vals, inner_cfg)?;
|
let table = expand_list(vals, inner_cfg)?;
|
||||||
|
|
||||||
match table {
|
match table {
|
||||||
Some(out) => {
|
Some(mut out) => {
|
||||||
let cfg = create_table_cfg(cfg, &out);
|
table_apply_config(&mut out, cfg);
|
||||||
let value = out.table.draw(cfg, width);
|
let value = out.table.draw(width);
|
||||||
match value {
|
match value {
|
||||||
Some(value) => Ok(Some(CellOutput::clean(value, out.count_rows, true))),
|
Some(value) => Ok(Some(CellOutput::clean(value, out.count_rows, true))),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
|
@ -539,7 +537,7 @@ fn expand_entry(item: &Value, cfg: Cfg<'_>) -> CellOutput {
|
||||||
let inner_cfg = cfg_expand_next_level(cfg.clone(), span);
|
let inner_cfg = cfg_expand_next_level(cfg.clone(), span);
|
||||||
let table = expand_list(vals, inner_cfg);
|
let table = expand_list(vals, inner_cfg);
|
||||||
|
|
||||||
let out = match table {
|
let mut out = match table {
|
||||||
Ok(Some(out)) => out,
|
Ok(Some(out)) => out,
|
||||||
_ => {
|
_ => {
|
||||||
let value = nu_value_to_string(item, cfg.opts.config, &cfg.opts.style_computer);
|
let value = nu_value_to_string(item, cfg.opts.config, &cfg.opts.style_computer);
|
||||||
|
@ -547,8 +545,9 @@ fn expand_entry(item: &Value, cfg: Cfg<'_>) -> CellOutput {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let table_config = create_table_cfg(&cfg, &out);
|
table_apply_config(&mut out, &cfg);
|
||||||
let table = out.table.draw(table_config, usize::MAX);
|
|
||||||
|
let table = out.table.draw(usize::MAX);
|
||||||
match table {
|
match table {
|
||||||
Some(table) => CellOutput::clean(table, out.count_rows, false),
|
Some(table) => CellOutput::clean(table, out.count_rows, false),
|
||||||
None => {
|
None => {
|
||||||
|
@ -592,20 +591,18 @@ fn list_to_string(
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_expand_table(out: TableOutput, term_width: usize, opts: &TableOpts<'_>) -> StringResult {
|
fn maybe_expand_table(mut out: TableOutput, term_width: usize) -> StringResult {
|
||||||
let mut table_config =
|
let total_width = out.table.total_width();
|
||||||
create_nu_table_config(opts.config, &opts.style_computer, &out, false, opts.mode);
|
|
||||||
let total_width = out.table.total_width(&table_config);
|
|
||||||
if total_width < term_width {
|
if total_width < term_width {
|
||||||
const EXPAND_THRESHOLD: f32 = 0.80;
|
const EXPAND_THRESHOLD: f32 = 0.80;
|
||||||
let used_percent = total_width as f32 / term_width as f32;
|
let used_percent = total_width as f32 / term_width as f32;
|
||||||
let need_expansion = total_width < term_width && used_percent > EXPAND_THRESHOLD;
|
let need_expansion = total_width < term_width && used_percent > EXPAND_THRESHOLD;
|
||||||
if need_expansion {
|
if need_expansion {
|
||||||
table_config.expand = true;
|
out.table.set_strategy(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let table = out.table.draw(table_config, term_width);
|
let table = out.table.draw(term_width);
|
||||||
|
|
||||||
Ok(table)
|
Ok(table)
|
||||||
}
|
}
|
||||||
|
@ -616,12 +613,11 @@ fn set_data_styles(table: &mut NuTable, styles: HashMap<Position, TextStyle>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_table_cfg(cfg: &Cfg<'_>, out: &TableOutput) -> crate::NuTableConfig {
|
fn table_apply_config(out: &mut TableOutput, cfg: &Cfg<'_>) {
|
||||||
create_nu_table_config(
|
configure_table(
|
||||||
|
out,
|
||||||
cfg.opts.config,
|
cfg.opts.config,
|
||||||
&cfg.opts.style_computer,
|
&cfg.opts.style_computer,
|
||||||
out,
|
|
||||||
false,
|
|
||||||
cfg.opts.mode,
|
cfg.opts.mode,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use nu_protocol::{Config, Record, ShellError, Value};
|
||||||
use crate::{
|
use crate::{
|
||||||
clean_charset, colorize_space,
|
clean_charset, colorize_space,
|
||||||
common::{
|
common::{
|
||||||
check_value, create_nu_table_config, get_empty_style, get_header_style, get_index_style,
|
check_value, configure_table, get_empty_style, get_header_style, get_index_style,
|
||||||
get_value_style, nu_value_to_string_colored, NuText, INDEX_COLUMN_NAME,
|
get_value_style, nu_value_to_string_colored, NuText, INDEX_COLUMN_NAME,
|
||||||
},
|
},
|
||||||
types::has_index,
|
types::has_index,
|
||||||
|
@ -30,15 +30,12 @@ fn list_table(input: &[Value], opts: TableOpts<'_>) -> Result<Option<String>, Sh
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
out.table.set_indent(
|
out.table.set_indent(opts.config.table.padding);
|
||||||
opts.config.table.padding.left,
|
|
||||||
opts.config.table.padding.right,
|
|
||||||
);
|
|
||||||
|
|
||||||
colorize_space(out.table.get_records_mut(), &opts.style_computer);
|
colorize_space(out.table.get_records_mut(), &opts.style_computer);
|
||||||
|
|
||||||
let config = create_nu_table_config(opts.config, &opts.style_computer, &out, false, opts.mode);
|
configure_table(&mut out, opts.config, &opts.style_computer, opts.mode);
|
||||||
let table = out.table.draw(config, opts.width);
|
let table = out.table.draw(opts.width);
|
||||||
|
|
||||||
Ok(table)
|
Ok(table)
|
||||||
}
|
}
|
||||||
|
@ -60,15 +57,11 @@ fn kv_table(record: &Record, opts: TableOpts<'_>) -> StringResult {
|
||||||
|
|
||||||
let mut table = NuTable::from(data);
|
let mut table = NuTable::from(data);
|
||||||
table.set_index_style(TextStyle::default_field());
|
table.set_index_style(TextStyle::default_field());
|
||||||
table.set_indent(
|
table.set_indent(opts.config.table.padding);
|
||||||
opts.config.table.padding.left,
|
|
||||||
opts.config.table.padding.right,
|
|
||||||
);
|
|
||||||
|
|
||||||
let out = TableOutput::from_table(table, false, true);
|
let mut out = TableOutput::from_table(table, false, true);
|
||||||
let table_config =
|
configure_table(&mut out, opts.config, &opts.style_computer, opts.mode);
|
||||||
create_nu_table_config(opts.config, &opts.style_computer, &out, false, opts.mode);
|
let table = out.table.draw(opts.width);
|
||||||
let table = out.table.draw(table_config, opts.width);
|
|
||||||
|
|
||||||
Ok(table)
|
Ok(table)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,11 @@ pub use expanded::ExpandedTable;
|
||||||
pub use general::JustTable;
|
pub use general::JustTable;
|
||||||
|
|
||||||
pub struct TableOutput {
|
pub struct TableOutput {
|
||||||
|
/// A table structure.
|
||||||
pub table: NuTable,
|
pub table: NuTable,
|
||||||
|
/// A flag whether a header was present in the table.
|
||||||
pub with_header: bool,
|
pub with_header: bool,
|
||||||
|
/// A flag whether a index was present in the table.
|
||||||
pub with_index: bool,
|
pub with_index: bool,
|
||||||
/// The value may be bigger then table.count_rows(),
|
/// The value may be bigger then table.count_rows(),
|
||||||
/// Specifically in case of expanded table we collect the whole structure size here.
|
/// Specifically in case of expanded table we collect the whole structure size here.
|
||||||
|
|
|
@ -69,9 +69,11 @@ pub fn clean_charset(text: &str) -> String {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if c < ' ' {
|
// note: Overall maybe we shall delete this check?
|
||||||
continue;
|
// it was made in order to cope with emojie issue.
|
||||||
}
|
// if c < ' ' && c != '\u{1b}' {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
buf.push(c);
|
buf.push(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,79 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use nu_table::{string_width, NuTable, NuTableConfig};
|
use nu_protocol::TrimStrategy;
|
||||||
|
use nu_table::{string_width, NuTable, TableTheme};
|
||||||
use tabled::grid::records::vec_records::Text;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct TestCase {
|
pub struct TestCase {
|
||||||
cfg: NuTableConfig,
|
theme: TableTheme,
|
||||||
|
with_header: bool,
|
||||||
|
with_footer: bool,
|
||||||
|
with_index: bool,
|
||||||
|
expand: bool,
|
||||||
|
strategy: TrimStrategy,
|
||||||
termwidth: usize,
|
termwidth: usize,
|
||||||
expected: Option<String>,
|
expected: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestCase {
|
impl TestCase {
|
||||||
pub fn new(cfg: NuTableConfig, termwidth: usize, expected: Option<String>) -> Self {
|
pub fn new(termwidth: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cfg,
|
|
||||||
termwidth,
|
termwidth,
|
||||||
expected,
|
expected: None,
|
||||||
|
theme: TableTheme::basic(),
|
||||||
|
with_header: false,
|
||||||
|
with_footer: false,
|
||||||
|
with_index: false,
|
||||||
|
expand: false,
|
||||||
|
strategy: TrimStrategy::truncate(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn expected(mut self, value: Option<String>) -> Self {
|
||||||
|
self.expected = value;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn theme(mut self, theme: TableTheme) -> Self {
|
||||||
|
self.theme = theme;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expand(mut self) -> Self {
|
||||||
|
self.expand = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn header(mut self) -> Self {
|
||||||
|
self.with_header = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn footer(mut self) -> Self {
|
||||||
|
self.with_footer = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn index(mut self) -> Self {
|
||||||
|
self.with_index = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trim(mut self, trim: TrimStrategy) -> Self {
|
||||||
|
self.strategy = trim;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Data = Vec<Vec<Text<String>>>;
|
type Data = Vec<Vec<Text<String>>>;
|
||||||
|
|
||||||
pub fn test_table<I: IntoIterator<Item = TestCase>>(data: Data, tests: I) {
|
pub fn test_table<I>(data: Data, tests: I)
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = TestCase>,
|
||||||
|
{
|
||||||
for (i, test) in tests.into_iter().enumerate() {
|
for (i, test) in tests.into_iter().enumerate() {
|
||||||
let actual = create_table(data.clone(), test.cfg.clone(), test.termwidth);
|
let actual = create_table(data.clone(), test.clone());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual, test.expected,
|
actual, test.expected,
|
||||||
|
@ -37,9 +87,14 @@ pub fn test_table<I: IntoIterator<Item = TestCase>>(data: Data, tests: I) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_table(data: Data, config: NuTableConfig, termwidth: usize) -> Option<String> {
|
pub fn create_table(data: Data, case: TestCase) -> Option<String> {
|
||||||
let table = NuTable::from(data);
|
let mut table = NuTable::from(data);
|
||||||
table.draw(config, termwidth)
|
table.set_theme(case.theme);
|
||||||
|
table.set_structure(case.with_index, case.with_header, case.with_footer);
|
||||||
|
table.set_trim(case.strategy);
|
||||||
|
table.set_strategy(case.expand);
|
||||||
|
|
||||||
|
table.draw(case.termwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_row(count_columns: usize) -> Vec<Text<String>> {
|
pub fn create_row(count_columns: usize) -> Vec<Text<String>> {
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
use common::{create_row, test_table, TestCase};
|
|
||||||
use nu_protocol::TrimStrategy;
|
use nu_protocol::TrimStrategy;
|
||||||
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
use nu_table::{NuTable, TableTheme as theme};
|
||||||
|
|
||||||
|
use common::{create_row, test_table, TestCase};
|
||||||
|
|
||||||
use tabled::grid::records::vec_records::Text;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn data_and_header_has_different_size_doesnt_work() {
|
fn data_and_header_has_different_size_doesnt_work() {
|
||||||
let table = NuTable::from(vec![create_row(5), create_row(5), create_row(5)]);
|
let mut table = NuTable::from(vec![create_row(5), create_row(5), create_row(5)]);
|
||||||
let cfg = NuTableConfig {
|
table.set_theme(theme::heavy());
|
||||||
theme: theme::heavy(),
|
table.set_structure(false, true, false);
|
||||||
with_header: true,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let table = table.draw(cfg.clone(), usize::MAX);
|
let table = table.draw(usize::MAX);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table.as_deref(),
|
table.as_deref(),
|
||||||
|
@ -30,7 +29,7 @@ fn data_and_header_has_different_size_doesnt_work() {
|
||||||
|
|
||||||
let table = NuTable::from(vec![create_row(5), create_row(5), create_row(5)]);
|
let table = NuTable::from(vec![create_row(5), create_row(5), create_row(5)]);
|
||||||
|
|
||||||
let table = table.draw(cfg, usize::MAX);
|
let table = table.draw(usize::MAX);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
table.as_deref(),
|
table.as_deref(),
|
||||||
|
@ -47,30 +46,27 @@ fn data_and_header_has_different_size_doesnt_work() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn termwidth_too_small() {
|
fn termwidth_too_small() {
|
||||||
let test_loop = |config: NuTableConfig| {
|
let tests = [
|
||||||
for i in 0..10 {
|
|
||||||
let table = NuTable::from(vec![create_row(5), create_row(5), create_row(5)]);
|
|
||||||
let table = table.draw(config.clone(), i);
|
|
||||||
|
|
||||||
assert!(table.is_none());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut cfg = NuTableConfig {
|
|
||||||
theme: theme::heavy(),
|
|
||||||
with_header: true,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
for case in [
|
|
||||||
TrimStrategy::truncate(None),
|
TrimStrategy::truncate(None),
|
||||||
TrimStrategy::truncate(Some(String::from("**"))),
|
TrimStrategy::truncate(Some(String::from("**"))),
|
||||||
TrimStrategy::truncate(Some(String::from(""))),
|
TrimStrategy::truncate(Some(String::from(""))),
|
||||||
TrimStrategy::wrap(false),
|
TrimStrategy::wrap(false),
|
||||||
TrimStrategy::wrap(true),
|
TrimStrategy::wrap(true),
|
||||||
] {
|
];
|
||||||
cfg.trim = case;
|
|
||||||
test_loop(cfg.clone());
|
let data = vec![create_row(5), create_row(5), create_row(5)];
|
||||||
|
|
||||||
|
for case in tests {
|
||||||
|
for i in 0..10 {
|
||||||
|
let mut table = NuTable::from(data.clone());
|
||||||
|
table.set_theme(theme::heavy());
|
||||||
|
table.set_structure(false, true, false);
|
||||||
|
table.set_trim(case.clone());
|
||||||
|
|
||||||
|
let table = table.draw(i);
|
||||||
|
|
||||||
|
assert!(table.is_none());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,30 +191,24 @@ fn width_control_test_0() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_width(data: Vec<Vec<Text<String>>>, tests: &[(usize, &str)]) {
|
fn test_width(data: Vec<Vec<Text<String>>>, tests: &[(usize, &str)]) {
|
||||||
let config = NuTableConfig {
|
|
||||||
theme: theme::heavy(),
|
|
||||||
trim: TrimStrategy::truncate(Some(String::from("..."))),
|
|
||||||
with_header: true,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let tests = tests.iter().map(|&(termwidth, expected)| {
|
let tests = tests.iter().map(|&(termwidth, expected)| {
|
||||||
TestCase::new(config.clone(), termwidth, Some(expected.to_owned()))
|
TestCase::new(termwidth)
|
||||||
|
.theme(theme::heavy())
|
||||||
|
.trim(TrimStrategy::truncate(Some(String::from("..."))))
|
||||||
|
.header()
|
||||||
|
.expected(Some(expected.to_owned()))
|
||||||
});
|
});
|
||||||
|
|
||||||
test_table(data, tests);
|
test_table(data, tests);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_trim(tests: &[(usize, Option<&str>)], trim: TrimStrategy) {
|
fn test_trim(tests: &[(usize, Option<&str>)], trim: TrimStrategy) {
|
||||||
let config = NuTableConfig {
|
|
||||||
theme: theme::heavy(),
|
|
||||||
with_header: true,
|
|
||||||
trim,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let tests = tests.iter().map(|&(termwidth, expected)| {
|
let tests = tests.iter().map(|&(termwidth, expected)| {
|
||||||
TestCase::new(config.clone(), termwidth, expected.map(|s| s.to_string()))
|
TestCase::new(termwidth)
|
||||||
|
.theme(theme::heavy())
|
||||||
|
.trim(trim.clone())
|
||||||
|
.header()
|
||||||
|
.expected(expected.map(|s| s.to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = vec![
|
let data = vec![
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
use common::{create_row, create_table};
|
use common::{create_row, create_table, TestCase};
|
||||||
|
|
||||||
use nu_table::{NuTableConfig, TableTheme as theme};
|
use nu_table::TableTheme as theme;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_expand() {
|
fn test_expand() {
|
||||||
let table = create_table(
|
let table = create_table(
|
||||||
vec![create_row(4); 3],
|
vec![create_row(4); 3],
|
||||||
NuTableConfig {
|
TestCase::new(50).theme(theme::rounded()).header().expand(),
|
||||||
theme: theme::rounded(),
|
|
||||||
with_header: true,
|
|
||||||
expand: true,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
50,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
use common::create_row as row;
|
use common::{create_row as row, TestCase};
|
||||||
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
use nu_table::{NuTable, TableTheme as theme};
|
||||||
use tabled::grid::records::vec_records::Text;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -452,27 +452,18 @@ fn test_with_love() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_table(data: Vec<Vec<Text<String>>>, with_header: bool, theme: theme) -> String {
|
fn create_table(data: Vec<Vec<Text<String>>>, with_header: bool, theme: theme) -> String {
|
||||||
let config = NuTableConfig {
|
let mut case = TestCase::new(usize::MAX).theme(theme);
|
||||||
theme,
|
if with_header {
|
||||||
with_header,
|
case = case.header();
|
||||||
..Default::default()
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let out = common::create_table(data, config, usize::MAX);
|
common::create_table(data, case).expect("not expected to get None")
|
||||||
|
|
||||||
out.expect("not expected to get None")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_table_with_size(data: Vec<Vec<Text<String>>>, with_header: bool, theme: theme) -> String {
|
fn create_table_with_size(data: Vec<Vec<Text<String>>>, with_header: bool, theme: theme) -> String {
|
||||||
let config = NuTableConfig {
|
let mut table = NuTable::from(data);
|
||||||
theme,
|
table.set_theme(theme);
|
||||||
with_header,
|
table.set_structure(false, with_header, false);
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let table = NuTable::from(data);
|
table.draw(usize::MAX).expect("not expected to get None")
|
||||||
|
|
||||||
table
|
|
||||||
.draw(config, usize::MAX)
|
|
||||||
.expect("not expected to get None")
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue