mirror of
https://github.com/nushell/nushell.git
synced 2025-05-05 23:42:56 +00:00
- A few days back I've got this idea regarding recalculus of width. Now it calculates step by step. So 1 loop over all data was removed. All though there's full recalculation in case of `header_on_border` 😞 (can be fixed..... but I decided to be short) In perfect world it also shall be refactored ...... - Also have done small refactoring to switch build table from `Vec<Vec<_>>>` to table itself. To hide internals (kind of still there's things which I don't like). It touched the `--expand` algorithm lightly you can see the tests changes. - And when doing that noticed one more opportunity, to remove HashMap usage and directly use `tabled::ColoredConfig`. Which reduces copy operations and allocations. - And fixed a small issue where trailing column being using deleted column styles.  To conclude optimizations; I did small testing and it's not slower. But I didn't get the faster results either. But I believe it must be faster well in all cases, I think maybe bigger tables must be tested. Maybe someone could have a few runs to compare performance. cc: @fdncred
119 lines
2.7 KiB
Rust
119 lines
2.7 KiB
Rust
#![allow(dead_code)]
|
|
|
|
use nu_protocol::TrimStrategy;
|
|
use nu_table::{string_width, NuTable, TableTheme};
|
|
use tabled::grid::records::vec_records::Text;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct TestCase {
|
|
theme: TableTheme,
|
|
with_header: bool,
|
|
with_footer: bool,
|
|
with_index: bool,
|
|
expand: bool,
|
|
strategy: TrimStrategy,
|
|
termwidth: usize,
|
|
expected: Option<String>,
|
|
}
|
|
|
|
impl TestCase {
|
|
pub fn new(termwidth: usize) -> Self {
|
|
Self {
|
|
termwidth,
|
|
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>>>;
|
|
|
|
pub fn test_table<I>(data: Data, tests: I)
|
|
where
|
|
I: IntoIterator<Item = TestCase>,
|
|
{
|
|
for (i, test) in tests.into_iter().enumerate() {
|
|
let actual = create_table(data.clone(), test.clone());
|
|
|
|
assert_eq!(
|
|
actual, test.expected,
|
|
"\nfail i={:?} termwidth={}",
|
|
i, test.termwidth
|
|
);
|
|
|
|
if let Some(table) = actual {
|
|
assert!(string_width(&table) <= test.termwidth);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn create_table(data: Data, case: TestCase) -> Option<String> {
|
|
let count_rows = data.len();
|
|
let count_cols = data[0].len();
|
|
|
|
let mut table = NuTable::new(count_rows, count_cols);
|
|
for (i, row) in data.into_iter().enumerate() {
|
|
table.set_row(i, row);
|
|
}
|
|
|
|
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>> {
|
|
let mut row = Vec::with_capacity(count_columns);
|
|
for i in 0..count_columns {
|
|
row.push(Text::new(i.to_string()));
|
|
}
|
|
|
|
row
|
|
}
|
|
|
|
pub fn cell(text: &str) -> Text<String> {
|
|
Text::new(text.to_string())
|
|
}
|