Fix issue with head on separation lines

This commit is contained in:
Maxim Zhiburt 2024-07-03 16:43:20 +03:00
parent 0cfd5fbece
commit 1ba01691b8

View File

@ -17,8 +17,8 @@ use tabled::{
},
},
settings::{
formatting::AlignmentStrategy, object::Segment, peaker::Peaker, themes::ColumnNames, Color,
Modify, Padding, Settings, TableOption, Width,
formatting::AlignmentStrategy, object::Segment, peaker::Peaker, themes::ColumnNames,
width::Truncate, Color, Modify, Padding, Settings, TableOption, Width,
},
Table,
};
@ -269,20 +269,51 @@ fn set_indent(table: &mut Table, left: usize, right: usize) {
fn set_border_head(table: &mut Table, with_footer: bool, wctrl: TableWidthCtrl) {
if with_footer {
let count_rows = table.count_rows();
let last_row_index = count_rows - 1;
// note: funnily last and row must be equal at this point but we do not rely on it just in case.
let mut first_row = GetRow(0, Vec::new());
let mut head_settings = GetRowSettings(0, AlignmentHorizontal::Left, None);
let mut last_row = GetRow(last_row_index, Vec::new());
table.with(&mut first_row);
table.with(&mut head_settings);
table.with(&mut last_row);
table.with(
Settings::default()
.with(wctrl)
.with(StripColorFromRow(0))
.with(StripColorFromRow(count_rows - 1))
.with(HeaderMove((0, 0), true))
.with(HeaderMove((count_rows - 1 - 1, count_rows - 1), false)),
.with(MoveRowNext::new(0, 0))
.with(MoveRowPrev::new(last_row_index - 1, last_row_index))
.with(SetLineHeaders::new(
0,
first_row.1,
head_settings.1,
head_settings.2.clone(),
))
.with(SetLineHeaders::new(
last_row_index,
last_row.1,
head_settings.1,
head_settings.2,
)),
);
} else {
let mut row = GetRow(0, Vec::new());
let mut row_opts = GetRowSettings(0, AlignmentHorizontal::Left, None);
table.with(&mut row);
table.with(&mut row_opts);
table.with(
Settings::default()
.with(wctrl)
.with(StripColorFromRow(0))
.with(HeaderMove((0, 0), true)),
.with(MoveRowNext::new(0, 0))
.with(SetLineHeaders::new(0, row.1, row_opts.1, row_opts.2)),
);
}
}
@ -729,50 +760,154 @@ fn build_width(records: &NuRecords, pad: usize) -> Vec<usize> {
widths
}
struct HeaderMove((usize, usize), bool);
struct GetRow(usize, Vec<String>);
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for HeaderMove {
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for &mut GetRow {
fn change(
self,
recs: &mut NuRecords,
_: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
let row = self.0;
self.1 = recs[row].iter().map(|c| c.as_ref().to_owned()).collect();
}
}
struct GetRowSettings(usize, AlignmentHorizontal, Option<Color>);
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig>
for &mut GetRowSettings
{
fn change(
self,
_: &mut NuRecords,
cfg: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
let row = self.0;
self.1 = *cfg.get_alignment_horizontal(Entity::Row(row));
self.2 = cfg
.get_colors()
.get_color((row, 0))
.cloned()
.map(Color::from);
}
}
struct SetLineHeaders {
line: usize,
columns: Vec<String>,
alignment: AlignmentHorizontal,
color: Option<Color>,
}
impl SetLineHeaders {
fn new(
line: usize,
columns: Vec<String>,
alignment: AlignmentHorizontal,
color: Option<Color>,
) -> Self {
Self {
line,
columns,
alignment,
color,
}
}
}
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for SetLineHeaders {
fn change(
self,
recs: &mut NuRecords,
cfg: &mut ColoredConfig,
dims: &mut CompleteDimensionVecRecords<'_>,
) {
let (row, line) = self.0;
if self.1 {
move_header_on_next(recs, cfg, dims, row, line);
} else {
move_header_on_prev(recs, cfg, dims, row, line);
}
let mut columns = self.columns;
match dims.get_widths() {
Some(widths) => {
columns = columns
.into_iter()
.zip(widths)
.map(|(s, width)| Truncate::truncate_text(&s, *width).into_owned())
.collect();
}
None => {
// we don't have widths cached; which means that NO widtds adjustmens were done
// which means we are OK to leave columns as they are.
}
};
set_column_names(
recs,
cfg,
dims,
columns,
self.line,
self.alignment,
self.color,
)
}
}
fn move_header_on_next(
recs: &mut NuRecords,
cfg: &mut ColoredConfig,
dims: &mut CompleteDimensionVecRecords<'_>,
struct MoveRowNext {
row: usize,
line: usize,
) {
}
impl MoveRowNext {
fn new(row: usize, line: usize) -> Self {
Self { row, line }
}
}
struct MoveRowPrev {
row: usize,
line: usize,
}
impl MoveRowPrev {
fn new(row: usize, line: usize) -> Self {
Self { row, line }
}
}
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for MoveRowNext {
fn change(
self,
recs: &mut NuRecords,
cfg: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
row_shift_next(recs, cfg, self.row, self.line);
}
}
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for MoveRowPrev {
fn change(
self,
recs: &mut NuRecords,
cfg: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
row_shift_prev(recs, cfg, self.row, self.line);
}
}
fn row_shift_next(recs: &mut NuRecords, cfg: &mut ColoredConfig, row: usize, line: usize) {
let count_rows = recs.count_rows();
let count_columns = recs.count_columns();
let has_line = cfg.has_horizontal(line, count_rows);
let has_next_line = cfg.has_horizontal(line + 1, count_rows);
let align = *cfg.get_alignment_horizontal(Entity::Row(row));
let color = cfg
.get_colors()
.get_color((row, 0))
.cloned()
.map(Color::from);
if !has_line && !has_next_line {
return;
}
if !has_line {
let head = remove_row(recs, row);
let _ = remove_row(recs, row);
let count_rows = recs.count_rows();
set_column_names(recs, cfg, dims, head, line, align, color);
shift_alignments_down(cfg, row, count_rows, count_columns);
shift_colors_down(cfg, row, count_rows, count_columns);
shift_lines_up(cfg, count_rows, &[line + 1]);
@ -780,47 +915,31 @@ fn move_header_on_next(
return;
}
let head = remove_row(recs, row);
let _ = remove_row(recs, row);
let count_rows = recs.count_rows();
set_column_names(recs, cfg, dims, head, line, align, color);
shift_alignments_down(cfg, row, count_rows, count_columns);
shift_colors_down(cfg, row, count_rows, count_columns);
remove_lines(cfg, count_rows, &[line + 1]);
shift_lines_up(cfg, count_rows, &[count_rows]);
}
fn move_header_on_prev(
recs: &mut NuRecords,
cfg: &mut ColoredConfig,
dims: &mut CompleteDimensionVecRecords<'_>,
row: usize,
line: usize,
) {
fn row_shift_prev(recs: &mut NuRecords, cfg: &mut ColoredConfig, row: usize, line: usize) {
let count_rows = recs.count_rows();
let count_columns = recs.count_columns();
let has_line = cfg.has_horizontal(line, count_rows);
let has_prev_line = cfg.has_horizontal(line - 1, count_rows);
let align = *cfg.get_alignment_horizontal(Entity::Row(row));
let color = cfg
.get_colors()
.get_color((row, 0))
.cloned()
.map(Color::from);
if !has_line && !has_prev_line {
return;
}
if !has_line {
let head = remove_row(recs, row);
let _ = remove_row(recs, row);
// shift_lines_down(table, &[line - 1]);
set_column_names(recs, cfg, dims, head, line - 1, align, color);
return;
}
let head = remove_row(recs, row);
let _ = remove_row(recs, row);
let count_rows = count_rows - 1;
set_column_names(recs, cfg, dims, head, line - 1, align, color);
shift_alignments_down(cfg, row, count_rows, count_columns);
shift_colors_down(cfg, row, count_rows, count_columns);
remove_lines(cfg, count_rows, &[line - 1]);