Skip to content

Commit

Permalink
tabled/ Change Highlight interface (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiburt authored Nov 13, 2024
1 parent e20e2f8 commit 49ec841
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 85 deletions.
3 changes: 1 addition & 2 deletions tabled/examples/highlight_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use tabled::{
settings::{
object::{Columns, Object, Rows},
style::BorderColor,
Color, Highlight, Style,
},
Table,
Expand All @@ -20,7 +19,7 @@ fn main() {

let mut table = Table::new(data);
table.with(Style::modern());
table.with(Highlight::color(target, BorderColor::filled(color)));
table.with(Highlight::colored(target, color));

println!("{table}");
}
113 changes: 58 additions & 55 deletions tabled/src/settings/highlight/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ use std::collections::HashSet;
use crate::{
grid::{
ansi::ANSIBuf,
config::{Border as GridBorder, ColoredConfig, Entity, Position, SpannedConfig},
config::{Border, ColoredConfig, Entity, Position, SpannedConfig},
records::{ExactRecords, Records},
},
settings::{object::Object, style::BorderColor, Border, Color, TableOption},
settings::{
object::Object,
style::{Border as ConstBorder, BorderColor},
Color, TableOption,
},
};

/// Highlight modifies a table style by changing a border of a target [`Table`] segment.
Expand Down Expand Up @@ -60,69 +64,65 @@ use crate::{
#[derive(Debug)]
pub struct Highlight<O> {
target: O,
border: HighlightInner,
}

#[derive(Debug)]
enum HighlightInner {
Border(GridBorder<char>),
// #[cfg(feature = "ansi")]
Color(GridBorder<ANSIBuf>),
// #[cfg(feature = "ansi")]
ColoredBorder(GridBorder<char>, GridBorder<ANSIBuf>),
border: Option<Border<char>>,
color: Option<Border<ANSIBuf>>,
}

impl<O> Highlight<O> {
/// Build a new instance of [`Highlight`],
/// highlighting by a color, while preserving existing border.
/// Build a new instance of [`Highlight`] with '*' char being used as changer.
///
/// BE AWARE: if target exceeds boundaries it may panic.
pub fn color(target: O, border: BorderColor) -> Self {
let color = border.into_inner();
let color = color.convert();

Self {
target,
border: HighlightInner::Color(color),
}
pub const fn new(target: O) -> Self {
Self::_new(target, None, None)
}

/// Build a new instance of [`Highlight`],
/// highlighting by a character.
///
/// BE AWARE: if target exceeds boundaries it may panic.
pub const fn outline(target: O, c: char) -> Self {
Self::new(target, Border::filled(c))
Self::_new(target, Some(Border::filled(c)), None)
}

/// Build a new instance of [`Highlight`],
/// highlighting by a color and a given character for a border.
///
/// BE AWARE: if target exceeds boundaries it may panic.
pub fn outline_colored<T, B, L, R>(target: O, c: char, color: Color) -> Self {
Self::colored(target, Border::filled(c), BorderColor::filled(color))
pub fn colored(target: O, color: Color) -> Self {
let color = Border::filled(&color).cloned().convert();
Self::_new(target, None, Some(color))
}

/// Build a new instance of [`Highlight`]
///
/// BE AWARE: if target exceeds boundaries it may panic.
pub const fn new<T, B, L, R>(target: O, border: Border<T, B, L, R>) -> Self {
/// Set a border for a [`Highlight`].
pub fn border<T, B, L, R>(self, border: ConstBorder<T, B, L, R>) -> Self {
let border = border.into_inner();
Self {
target,
border: HighlightInner::Border(border.into_inner()),
target: self.target,
border: Some(border),
color: self.color,
}
}

/// Build a new instance of [`Highlight`] colored.
///
/// BE AWARE: if target exceeds boundaries it may panic.
pub fn colored<T, B, L, R>(target: O, border: Border<T, B, L, R>, color: BorderColor) -> Self {
/// Set a border color for a [`Highlight`].
pub fn color(self, border: BorderColor) -> Self {
let border = border.into_inner();
let color = color.into_inner().convert();
let border = border.convert();

Self {
target: self.target,
border: self.border,
color: Some(border),
}
}

/// Build a new instance of [`Highlight`]
///
/// BE AWARE: if target exceeds boundaries it may panic.
const fn _new(target: O, border: Option<Border<char>>, color: Option<Border<ANSIBuf>>) -> Self {
Self {
target,
border: HighlightInner::ColoredBorder(border, color),
border,
color,
}
}
}
Expand All @@ -139,19 +139,26 @@ where
let cells = self.target.cells(records);
let segments = split_segments(cells, count_rows, count_cols);

for sector in segments {
match &self.border {
HighlightInner::Border(border) => {
set_border(cfg, &sector, *border);
match (self.border, self.color) {
(None, Some(color)) => {
for sector in segments {
set_border_color(cfg, &sector, &color);
}
HighlightInner::Color(color) => {
set_border_color(cfg, &sector, color);
}
(Some(border), None) => {
for sector in segments {
set_border(cfg, &sector, border);
}
HighlightInner::ColoredBorder(border, color) => {
set_border(cfg, &sector, *border);
set_border_color(cfg, &sector, color);
}
(Some(border), Some(color)) => {
for sector in segments {
set_border(cfg, &sector, border);
set_border_color(cfg, &sector, &color);
}
}
(None, None) => {
// noop
}
}
}

Expand All @@ -160,11 +167,7 @@ where
}
}

fn set_border_color(
cfg: &mut SpannedConfig,
sector: &HashSet<Position>,
border: &GridBorder<ANSIBuf>,
) {
fn set_border_color(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: &Border<ANSIBuf>) {
if sector.is_empty() {
return;
}
Expand Down Expand Up @@ -252,7 +255,7 @@ fn is_segment_connected(segment1: &HashSet<Position>, segment2: &HashSet<Positio
false
}

fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: GridBorder<char>) {
fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: Border<char>) {
if sector.is_empty() {
return;
}
Expand All @@ -266,8 +269,8 @@ fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: GridB
fn build_cell_border<T>(
sector: &HashSet<Position>,
(row, col): Position,
border: &GridBorder<T>,
) -> GridBorder<T>
border: &Border<T>,
) -> Border<T>
where
T: Default + Clone,
{
Expand All @@ -281,7 +284,7 @@ where
let this_has_left_bottom_neighbor = is_there_left_bottom_cell(sector, row, col);
let this_has_right_bottom_neighbor = is_there_right_bottom_cell(sector, row, col);

let mut cell_border = GridBorder::default();
let mut cell_border = Border::default();
if let Some(c) = border.top.clone() {
if !cell_has_top_neighbor {
cell_border.top = Some(c.clone());
Expand Down
6 changes: 3 additions & 3 deletions tabled/src/settings/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,16 @@ mod vertical_line;
#[cfg(feature = "std")]
mod border_color;
#[cfg(feature = "std")]
mod line_text;
#[cfg(feature = "std")]
mod line_char;
#[cfg(feature = "std")]
mod line_text;
#[cfg(feature = "std")]
mod span_border_correction;

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub use self::{
border_color::BorderColor, line_text::LineText, line_char::LineChar,
border_color::BorderColor, line_char::LineChar, line_text::LineText,
span_border_correction::BorderSpanCorrection,
};

Expand Down
38 changes: 18 additions & 20 deletions tabled/tests/settings/highlingt_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use testing_table::{static_table, test_table};

test_table!(
highlingt_object_exceeds_boundaries,
Matrix::new(3, 3).with(Style::modern()).with(Highlight::new(Cell::new(1000, 0), Border::filled('+'))),
Matrix::new(3, 3).with(Style::modern()).with(Highlight::outline(Cell::new(1000, 0), '+')),
"┌───┬──────────┬──────────┬──────────┐"
"│ N │ column 0 │ column 1 │ column 2 │"
"├───┼──────────┼──────────┼──────────┤"
Expand All @@ -30,16 +30,16 @@ test_table!(
highlingt_empty_table,
Builder::default()
.build()
.with(Highlight::new(Segment::all(), Border::filled('+'))),
.with(Highlight::outline(Segment::all(), '+')),
""
);

test_table!(
highlingt_cell,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(Cell::new(0, 0), Border::filled('+')))
.with(Highlight::new(Cell::new(1, 1), Border::filled('*'))),
.with(Highlight::outline(Cell::new(0, 0), '+'))
.with(Highlight::outline(Cell::new(1, 1), '*')),
"+++++──────────┬──────────┬──────────┐"
"+ N + column 0 │ column 1 │ column 2 │"
"++++************──────────┼──────────┤"
Expand All @@ -55,8 +55,8 @@ test_table!(
highlingt_row,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(Rows::single(0), Border::filled('+')))
.with(Highlight::new(Rows::single(3), Border::filled('*'))),
.with(Highlight::outline(Rows::single(0), '+'))
.with(Highlight::outline(Rows::single(3), '*')),
"++++++++++++++++++++++++++++++++++++++"
"+ N │ column 0 │ column 1 │ column 2 +"
"++++++++++++++++++++++++++++++++++++++"
Expand All @@ -72,8 +72,8 @@ test_table!(
highlingt_column,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(Columns::single(0), Border::filled('+')))
.with(Highlight::new(Columns::single(2), Border::filled('*'))),
.with(Highlight::new(Columns::single(0)).border(Border::filled('+')))
.with(Highlight::new(Columns::single(2)).border(Border::filled('*'))),
"+++++──────────************──────────┐"
"+ N + column 0 * column 1 * column 2 │"
"+───+──────────*──────────*──────────┤"
Expand All @@ -89,7 +89,7 @@ test_table!(
highlingt_row_range,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(Rows::new(1..3), Border::filled('+'))),
.with(Highlight::outline(Rows::new(1..3), '+')),
"┌───┬──────────┬──────────┬──────────┐"
"│ N │ column 0 │ column 1 │ column 2 │"
"++++++++++++++++++++++++++++++++++++++"
Expand All @@ -105,7 +105,7 @@ test_table!(
highlingt_column_range,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(Columns::new(..2), Border::filled('+'))),
.with(Highlight::outline(Columns::new(..2), '+')),
"++++++++++++++++──────────┬──────────┐"
"+ N │ column 0 + column 1 │ column 2 │"
"+───┼──────────+──────────┼──────────┤"
Expand All @@ -121,8 +121,7 @@ test_table!(
highlingt_frame,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(
Frame,
.with(Highlight::new(Frame).border(
Border::filled('+')
.set_corner_top_left('*')
.set_corner_top_right('#')
Expand All @@ -144,8 +143,7 @@ test_table!(
highlingt_full,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(
Segment::all(),
.with(Highlight::new(Segment::all()).border(
Border::filled('+')
.set_corner_top_left('*')
.set_corner_top_right('#')
Expand All @@ -167,8 +165,8 @@ test_table!(
highlingt_single_column,
Matrix::table(3, 0)
.with(Style::modern())
.with(Highlight::new(Cell::new(0, 0), Border::new().set_left('*').set_top('x')))
.with(Highlight::new(Rows::new(1..3), Border::new().set_left('n'))),
.with(Highlight::new(Cell::new(0, 0)).border(Border::new().set_left('*').set_top('x')))
.with(Highlight::new(Rows::new(1..3)).border(Border::new().set_left('n'))),
"┌xxx┐"
"* N │"
"├───┤"
Expand All @@ -184,9 +182,9 @@ test_table!(
highlingt_several_times,
Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new(Frame, Border::filled('*')))
.with(Highlight::new(Cell::new(1, 1), Border::filled('#')))
.with(Highlight::new(Columns::single(3), Border::filled('x'))),
.with(Highlight::outline(Frame, '*'))
.with(Highlight::outline(Cell::new(1, 1), '#'))
.with(Highlight::outline(Columns::single(3), 'x')),
"**************************xxxxxxxxxxxx"
"* N │ column 0 │ column 1 x column 2 x"
"*───############──────────x──────────x"
Expand Down Expand Up @@ -233,7 +231,7 @@ fn highlingt_complex_figures() {

let table = Matrix::new(3, 3)
.with(Style::modern())
.with(Highlight::new($object, border))
.with(Highlight::new($object).border(border))
.to_string();

assert_eq!(table, $expected);
Expand Down
4 changes: 2 additions & 2 deletions tabled/tests/settings/rotate_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ test_table!(
test_table!(
rotate_preserve_border_styles_test_0,
Matrix::iter([(123, 456, 789), (234, 567, 891), (111, 222, 333)])
.with(Highlight::new(Rows::single(0), Border::new().set_top('*')))
.with(Highlight::new(Rows::single(0)).border(Border::new().set_top('*')))
.with(Rotate::Left),
"+*****************+-----+"
"| i32 | 789 | 891 | 333 |"
Expand All @@ -154,7 +154,7 @@ test_table!(
test_table!(
rotate_preserve_border_styles_test_1,
Matrix::iter([(123, 456, 789), (234, 567, 891), (111, 222, 333)])
.with(Highlight::new(Cell::new(0, 2), Border::new().set_bottom('*')))
.with(Highlight::new(Cell::new(0, 2)).border(Border::new().set_bottom('*')))
.with(Rotate::Left),
"+-----+-----+-----+-----+"
"| i32 | 789 | 891 | 333 |"
Expand Down
Loading

0 comments on commit 49ec841

Please sign in to comment.