Repository: zhiburt/tabled
Pull request #444 (2024-11-13 18:24:43)

tabled/ Update show example


Patch:
diff --git a/tabled/examples/highlight_color.rs b/tabled/examples/highlight_color.rs
index b9f45e3..af21e24 100644
--- a/tabled/examples/highlight_color.rs
+++ b/tabled/examples/highlight_color.rs
@@ -6,6 +6,7 @@
 use tabled::{
     settings::{
         object::{Columns, Object, Rows},
+        style::BorderColor,
         Color, Highlight, Style,
     },
     Table,
@@ -19,7 +20,7 @@ fn main() {
 
     let mut table = Table::new(data);
     table.with(Style::modern());
-    table.with(Highlight::colored(target, color));
+    table.with(Highlight::color(target, BorderColor::filled(color)));
 
     println!("{table}");
 }
diff --git a/tabled/examples/show/src/main.rs b/tabled/examples/show/src/main.rs
index db4dfa6..b5019bf 100644
--- a/tabled/examples/show/src/main.rs
+++ b/tabled/examples/show/src/main.rs
@@ -11,12 +11,12 @@
 //!
 //! Credit for data: https://www.boxofficemojo.com/
 
-use clap::Parser;
 use std::{
     io::{stdout, Stdout, StdoutLock, Write},
     time::Duration,
 };
 
+use clap::Parser;
 use crossterm::{
     cursor, queue,
     style::Stylize,
@@ -26,8 +26,8 @@ use crossterm::{
 use tabled::{
     settings::{
         object::{Columns, Object, Rows},
-        style::{Border, BorderColor, BorderText, Style},
-        Alignment, Color, Disable, Format, Highlight, Margin, Modify, Panel, Width,
+        style::{Border, BorderColor, LineText, Style},
+        Alignment, Color, Disable, Format, Highlight, Margin, Panel, Width,
     },
     Table, Tabled,
 };
@@ -131,121 +131,122 @@ fn run(movies: &[Movie], debug: bool) {
 fn print_movies(p: &mut impl Printer, movies: &[Movie]) {
     #[rustfmt::skip]
     let create_titles_actions: Vec<Action> = vec![
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(1..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(2..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(3..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(4..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(5..))).with(Style::modern()).clone()),
+        detached_action(|t| { t.with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(1..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(2..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(3..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(4..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(1..))).with(Disable::column(Columns::new(5..))).with(Style::modern()); }),
     ];
 
     #[rustfmt::skip]
     let add_movies_actions: Vec<Action> = vec![
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(2..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(3..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(4..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(5..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(6..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(7..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(8..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(9..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(10..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(11..))).with(Style::modern()).clone()),
-        detached_action(|_, m| Table::new(m).with(Disable::row(Rows::new(12..))).with(Style::modern()).clone()),
+        detached_action(|t| { t.with(Disable::row(Rows::new(2..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(3..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(4..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(5..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(6..))).with(Style::modern()); }),
+        detached_action(|t| { t.with(Disable::row(Rows::new(7..))).with(Style::modern()); }),
     ];
 
     #[rustfmt::skip]
     let add_summary_actions: Vec<Action> = vec![
-        full_action(|_, m, _| {
-            let mut table = Table::builder(m);
-            table.push_record(["", "", "", "", ""]);
+        new_action(|m| {
+            let mut b = Table::builder(m);
+            b.push_record(["", "", "", "", ""]);
             
-            table.build().with(Style::modern()).clone()
+            let mut table = b.build();
+            table.with(Style::modern());
+
+            table
         }),
-        action(|mut t| t.with(Modify::new(Rows::last().not(Columns::new(..2)).not(Columns::new(3..))).with(">= $281,000,000")).clone()),
-        action(|mut t| t.with(Modify::new(Rows::last().not(Columns::new(..3)).not(Columns::new(4..))).with("$394,835,565")).clone()),
-        action(|mut t| t.with(Modify::new(Rows::last().not(Columns::new(..4)).not(Columns::new(5..))).with("$5,930,687,178")).clone()),
+        action(|t| { t.modify(Rows::last().not(Columns::new(..2)).not(Columns::new(3..)), ">= $281,000,000"); }),
+        action(|t| { t.modify(Rows::last().not(Columns::new(..3)).not(Columns::new(4..)), "$394,835,565"); }),
+        action(|t| { t.modify(Rows::last().not(Columns::new(..4)).not(Columns::new(5..)), "$5,930,687,178"); }),
     ];
 
     #[rustfmt::skip]
     let formatting_actions: Vec<Action> = vec![
-        action(|mut t| t.with(Modify::new(Columns::single(0)).with(Alignment::right())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(1)).with(Alignment::right())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(2)).with(Alignment::right())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(3)).with(Alignment::right())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(4)).with(Alignment::right())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(5)).with(Alignment::right())).clone()),
+        action(|t| { t.modify(Columns::single(0), Alignment::right()); }),
+        action(|t| { t.modify(Columns::single(1), Alignment::right()); }),
+        action(|t| { t.modify(Columns::single(2), Alignment::right()); }),
+        action(|t| { t.modify(Columns::single(3), Alignment::right()); }),
+        action(|t| { t.modify(Columns::single(4), Alignment::right()); }),
+        action(|t| { t.modify(Columns::single(5), Alignment::right()); }),
         //
-        action(|mut t| t.with(Modify::new(Columns::single(0)).with(Alignment::left())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(1)).with(Alignment::left())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(2)).with(Alignment::left())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(3)).with(Alignment::left())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(4)).with(Alignment::left())).clone()),
-        action(|mut t| t.with(Modify::new(Columns::single(5)).with(Alignment::left())).clone()),
+        action(|t| { t.modify(Columns::single(0), Alignment::left()); }),
+        action(|t| { t.modify(Columns::single(1), Alignment::left()); }),
+        action(|t| { t.modify(Columns::single(2), Alignment::left()); }),
+        action(|t| { t.modify(Columns::single(3), Alignment::left()); }),
+        action(|t| { t.modify(Columns::single(4), Alignment::left()); }),
+        action(|t| { t.modify(Columns::single(5), Alignment::left()); }),
     ];
 
     #[rustfmt::skip]
     let style_actions: Vec<Action> = vec![
-        action(|mut t| t.with(Style::extended()).clone()),
-        action(|mut t| t.with(Style::ascii()).clone()),
-        action(|mut t| t.with(Style::rounded()).clone()),
-        action(|mut t| t.with(Style::psql()).clone()),
-        action(|mut t| t.with(Style::markdown()).clone()),
-        action(|mut t| t.with(Style::ascii_rounded()).clone()),
-        action(|mut t| t.with(Style::blank()).clone()),
+        action(|t| { t.with(Style::extended()); } ),
+        action(|t| { t.with(Style::ascii()); } ),
+        action(|t| { t.with(Style::rounded()); } ),
+        action(|t| { t.with(Style::psql()); } ),
+        action(|t| { t.with(Style::markdown()); } ),
+        action(|t| { t.with(Style::ascii_rounded()); } ),
+        action(|t| { t.with(Style::blank()); } ),
     ];
 
     let border_colors_actions: Vec<Action> = vec![];
 
     #[rustfmt::skip]
     let panel_actions: Vec<Action> = vec![
-        action(|mut t| t.with(Panel::header("The Lord of the Rings")).with(Modify::new(Rows::first()).with(Alignment::center())).clone()),
-        action(|mut t| t
-            .with(Highlight::colored(Rows::single(2), BorderColor::default().top(Color::FG_YELLOW)))
-            .with(Highlight::new(Rows::single(2), Border::default().top('━')))
-            .clone()),
-        action(|mut t| t
-            .with(Highlight::colored(Rows::last(), BorderColor::default().top(Color::FG_YELLOW)))
-            .with(Highlight::new(Rows::last(), Border::default().top('━')))
-            .clone()),
-        full_action(|mut t, m, _| {
+        action(|t| {
+            t.with(Panel::header("The Lord of the Rings"));
+            t.modify(Rows::first(), Alignment::center());
+        }),
+        action(|t| {
+            t.with(Highlight::new(Rows::single(2)).color(BorderColor::default().top(Color::FG_YELLOW)));
+            t.with(Highlight::new(Rows::single(2)).border(Border::new().set_top('━')));
+        }),
+        action(|t| {
+            t.with(Highlight::new(Rows::last()).color(BorderColor::default().top(Color::FG_YELLOW)));
+            t.with(Highlight::new(Rows::last()).border(Border::new().set_top('━')));
+        }),
+        action(|t| {
             let color = Color::try_from(" ".black().on_yellow().to_string()).unwrap();
-            t.with(BorderText::new("Statistics").horizontal(m.len()+2).color(color)).clone()
+            t.with(LineText::new("Statistics", Rows::last()).color(color));
         }),
     ];
 
     #[rustfmt::skip]
     let colorization_actions: Vec<Action> = vec![
-        action(|mut t| t.with(Modify::new(Rows::single(1).and(Rows::last()).not(Columns::new(..0)).not(Columns::new(1..))).with(Format::content(|s| s.white().bold().to_string()))).clone()),
-        action(|mut t| t.with(Modify::new(Rows::single(1).and(Rows::last()).not(Columns::new(..1)).not(Columns::new(2..))).with(Format::content(|s| s.white().bold().to_string()))).clone()),
-        action(|mut t| t.with(Modify::new(Rows::single(1).and(Rows::last()).not(Columns::new(..2)).not(Columns::new(3..))).with(Format::content(|s| s.red().bold().to_string()))).clone()),
-        action(|mut t| t.with(Modify::new(Rows::single(1).and(Rows::last()).not(Columns::new(..3)).not(Columns::new(4..))).with(Format::content(|s| s.green().bold().to_string()))).clone()),
-        action(|mut t| t.with(Modify::new(Rows::single(1).and(Rows::last()).not(Columns::new(..4)).not(Columns::new(5..))).with(Format::content(|s| s.blue().bold().to_string()))).clone()),
+        action(|t| { t.modify(Rows::single(1).and(Rows::last()).intersect(Columns::single(0)), Format::content(|s| s.white().bold().to_string())); }),
+        action(|t| { t.modify(Rows::single(1).and(Rows::last()).intersect(Columns::single(1)), Format::content(|s| s.white().bold().to_string())); }),
+        action(|t| { t.modify(Rows::single(1).and(Rows::last()).intersect(Columns::single(2)), Format::content(|s| s.red().bold().to_string())); }),
+        action(|t| { t.modify(Rows::single(1).and(Rows::last()).intersect(Columns::single(3)), Format::content(|s| s.green().bold().to_string())); }),
+        action(|t| { t.modify(Rows::single(1).and(Rows::last()).intersect(Columns::single(4)), Format::content(|s| s.blue().bold().to_string())); }),
     ];
 
     #[rustfmt::skip]
     let resize_actions: Vec<Action> = vec![
-        detached_action(|mut t, _| t.with(Width::wrap(115).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(110).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(105).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(100).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(95).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(90).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(80).keep_words()).clone()),
+        detached_action(|t| { t.with(Width::wrap(115).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(110).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(105).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(100).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(95).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(90).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(80).keep_words(true)); }),
         //
-        detached_action(|mut t, _| t.with(Width::wrap(90).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(95).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(100).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(105).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(110).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(115).keep_words()).clone()),
-        detached_action(|mut t, _| t.with(Width::wrap(120).keep_words()).clone()),
+        detached_action(|t| { t.with(Width::wrap(90).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(95).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(100).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(105).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(110).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(115).keep_words(true)); }),
+        detached_action(|t| { t.with(Width::wrap(120).keep_words(true)); }),
         //
-        detached_action(|mut t, _| t.with(Width::increase(125)).clone()),
-        detached_action(|mut t, _| t.with(Width::increase(130)).clone()),
-        detached_action(|mut t, _| t.with(Width::increase(135)).clone()),
-        detached_action(|mut t, _| t.with(Width::increase(140)).clone()),
-        detached_action(|mut t, _| t.with(Width::increase(145)).clone()),
-        detached_action(|mut t, _| t.with(Width::increase(150)).clone()),
+        detached_action(|t| { t.with(Width::increase(125)); }),
+        detached_action(|t| { t.with(Width::increase(130)); }),
+        detached_action(|t| { t.with(Width::increase(135)); }),
+        detached_action(|t| { t.with(Width::increase(140)); }),
+        detached_action(|t| { t.with(Width::increase(145)); }),
+        detached_action(|t| { t.with(Width::increase(150)); }),
     ];
 
     let mut runner = Runner::new(movies);
@@ -271,22 +272,32 @@ struct Context {
     ignore_table: bool,
 }
 
-fn detached_action<F>(f: F) -> Action
+fn action<F>(f: F) -> Action
 where
-    F: Fn(Table, Vec<Movie>) -> Table + 'static,
+    F: Fn(&mut Table) + 'static,
 {
-    Box::new(move |table, m, ctx| {
-        ctx.ignore_table = true;
-        f(table, m.to_vec())
+    Box::new(move |mut t, _, _| {
+        f(&mut t);
+        t
     })
 }
 
-fn full_action<F: Fn(Table, &[Movie], &mut Context) -> Table + 'static>(f: F) -> Action {
-    Box::new(move |t, m, ctx| f(t, m, ctx))
+fn detached_action<F>(f: F) -> Action
+where
+    F: Fn(&mut Table) + 'static,
+{
+    Box::new(move |mut table, _, ctx| {
+        ctx.ignore_table = true;
+        f(&mut table);
+        table
+    })
 }
 
-fn action<F: Fn(Table) -> Table + 'static>(f: F) -> Action {
-    Box::new(move |t, _, _| f(t))
+fn new_action<F>(f: F) -> Action
+where
+    F: Fn(Vec<Movie>) -> Table + 'static,
+{
+    Box::new(move |_, m, _| f(m.to_vec()))
 }
 
 impl<'a> Runner<'a> {
@@ -364,13 +375,11 @@ impl Printer for BasicPrinter<'_> {
         I: IntoIterator<Item = Table>,
     {
         let left_padding = Margin::new(10, 0, 0, 0);
-        for (_i, mut frame) in frames.into_iter().enumerate() {
+        for mut frame in frames.into_iter() {
             frame.with(left_padding.clone());
 
             queue!(self.stdout, Clear(ClearType::All), cursor::MoveTo(0, 7)).unwrap();
 
-            // writeln!(&mut self.stdout, "i={}", _i).unwrap();
-
             self.stdout.write_all(frame.to_string().as_bytes()).unwrap();
             self.stdout.flush().unwrap();
 
diff --git a/tabled/src/settings/highlight/mod.rs b/tabled/src/settings/highlight/mod.rs
index 6a61ab0..89aff0c 100644
--- a/tabled/src/settings/highlight/mod.rs
+++ b/tabled/src/settings/highlight/mod.rs
@@ -8,14 +8,10 @@ use std::collections::HashSet;
 use crate::{
     grid::{
         ansi::ANSIBuf,
-        config::{Border, ColoredConfig, Entity, Position, SpannedConfig},
+        config::{Border as GridBorder, ColoredConfig, Entity, Position, SpannedConfig},
         records::{ExactRecords, Records},
     },
-    settings::{
-        object::Object,
-        style::{Border as ConstBorder, BorderColor},
-        Color, TableOption,
-    },
+    settings::{object::Object, style::BorderColor, Border, Color, TableOption},
 };
 
 /// Highlight modifies a table style by changing a border of a target [`Table`] segment.
@@ -64,16 +60,31 @@ use crate::{
 #[derive(Debug)]
 pub struct Highlight<O> {
     target: O,
-    border: Option<Border<char>>,
-    color: Option<Border<ANSIBuf>>,
+    border: HighlightInner,
+}
+
+#[derive(Debug)]
+enum HighlightInner {
+    Border(GridBorder<char>),
+    // #[cfg(feature = "ansi")]
+    Color(GridBorder<ANSIBuf>),
+    // #[cfg(feature = "ansi")]
+    ColoredBorder(GridBorder<char>, GridBorder<ANSIBuf>),
 }
 
 impl<O> Highlight<O> {
-    /// Build a new instance of [`Highlight`] with '*' char being used as changer.
+    /// Build a new instance of [`Highlight`],
+    /// highlighting by a color, while preserving existing border.
     ///
     /// BE AWARE: if target exceeds boundaries it may panic.
-    pub const fn new(target: O) -> Self {
-        Self::_new(target, None, None)
+    pub fn color(target: O, border: BorderColor) -> Self {
+        let color = border.into_inner();
+        let color = color.convert();
+
+        Self {
+            target,
+            border: HighlightInner::Color(color),
+        }
     }
 
     /// Build a new instance of [`Highlight`],
@@ -81,48 +92,37 @@ impl<O> Highlight<O> {
     ///
     /// BE AWARE: if target exceeds boundaries it may panic.
     pub const fn outline(target: O, c: char) -> Self {
-        Self::_new(target, Some(Border::filled(c)), None)
+        Self::new(target, Border::filled(c))
     }
 
     /// 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 colored(target: O, color: Color) -> Self {
-        let color = Border::filled(&color).cloned().convert();
-        Self::_new(target, None, Some(color))
-    }
-
-    /// 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: self.target,
-            border: Some(border),
-            color: self.color,
-        }
+    pub fn outline_colored<T, B, L, R>(target: O, c: char, color: Color) -> Self {
+        Self::colored(target, Border::filled(c), BorderColor::filled(color))
     }
 
-    /// Set a border color for a [`Highlight`].
-    pub fn color(self, border: BorderColor) -> Self {
-        let border = border.into_inner();
-        let border = border.convert();
-
+    /// 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 {
         Self {
-            target: self.target,
-            border: self.border,
-            color: Some(border),
+            target,
+            border: HighlightInner::Border(border.into_inner()),
         }
     }
 
-    /// Build a new instance of [`Highlight`]
+    /// Build a new instance of [`Highlight`] colored.
     ///
     /// BE AWARE: if target exceeds boundaries it may panic.
-    const fn _new(target: O, border: Option<Border<char>>, color: Option<Border<ANSIBuf>>) -> Self {
+    pub fn colored<T, B, L, R>(target: O, border: Border<T, B, L, R>, color: BorderColor) -> Self {
+        let border = border.into_inner();
+        let color = color.into_inner().convert();
+
         Self {
             target,
-            border,
-            color,
+            border: HighlightInner::ColoredBorder(border, color),
         }
     }
 }
@@ -139,26 +139,19 @@ where
         let cells = self.target.cells(records);
         let segments = split_segments(cells, count_rows, count_cols);
 
-        match (self.border, self.color) {
-            (None, Some(color)) => {
-                for sector in segments {
-                    set_border_color(cfg, &sector, &color);
+        for sector in segments {
+            match &self.border {
+                HighlightInner::Border(border) => {
+                    set_border(cfg, &sector, *border);
                 }
-            }
-            (Some(border), None) => {
-                for sector in segments {
-                    set_border(cfg, &sector, border);
+                HighlightInner::Color(color) => {
+                    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);
+                HighlightInner::ColoredBorder(border, color) => {
+                    set_border(cfg, &sector, *border);
+                    set_border_color(cfg, &sector, color);
                 }
             }
-            (None, None) => {
-                // noop
-            }
         }
     }
 
@@ -167,7 +160,11 @@ where
     }
 }
 
-fn set_border_color(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: &Border<ANSIBuf>) {
+fn set_border_color(
+    cfg: &mut SpannedConfig,
+    sector: &HashSet<Position>,
+    border: &GridBorder<ANSIBuf>,
+) {
     if sector.is_empty() {
         return;
     }
@@ -255,7 +252,7 @@ fn is_segment_connected(segment1: &HashSet<Position>, segment2: &HashSet<Positio
     false
 }
 
-fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: Border<char>) {
+fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: GridBorder<char>) {
     if sector.is_empty() {
         return;
     }
@@ -269,8 +266,8 @@ fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<Position>, border: Borde
 fn build_cell_border<T>(
     sector: &HashSet<Position>,
     (row, col): Position,
-    border: &Border<T>,
-) -> Border<T>
+    border: &GridBorder<T>,
+) -> GridBorder<T>
 where
     T: Default + Clone,
 {
@@ -284,7 +281,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 = Border::default();
+    let mut cell_border = GridBorder::default();
     if let Some(c) = border.top.clone() {
         if !cell_has_top_neighbor {
             cell_border.top = Some(c.clone());
diff --git a/tabled/src/settings/style/mod.rs b/tabled/src/settings/style/mod.rs
index 39284ea..3bdefc3 100644
--- a/tabled/src/settings/style/mod.rs
+++ b/tabled/src/settings/style/mod.rs
@@ -105,16 +105,16 @@ mod vertical_line;
 #[cfg(feature = "std")]
 mod border_color;
 #[cfg(feature = "std")]
-mod line_char;
-#[cfg(feature = "std")]
 mod line_text;
 #[cfg(feature = "std")]
+mod line_char;
+#[cfg(feature = "std")]
 mod span_border_correction;
 
 #[cfg(feature = "std")]
 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
 pub use self::{
-    border_color::BorderColor, line_char::LineChar, line_text::LineText,
+    border_color::BorderColor, line_text::LineText, line_char::LineChar,
     span_border_correction::BorderSpanCorrection,
 };
 


Test patch:
diff --git a/tabled/tests/settings/highlingt_test.rs b/tabled/tests/settings/highlingt_test.rs
index 8b6a9dc..543932b 100644
--- a/tabled/tests/settings/highlingt_test.rs
+++ b/tabled/tests/settings/highlingt_test.rs
@@ -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::outline(Cell::new(1000, 0), '+')),
+    Matrix::new(3, 3).with(Style::modern()).with(Highlight::new(Cell::new(1000, 0), Border::filled('+'))),
     "┌───┬──────────┬──────────┬──────────┐"
     "│ N │ column 0 │ column 1 │ column 2 │"
     "├───┼──────────┼──────────┼──────────┤"
@@ -30,7 +30,7 @@ test_table!(
     highlingt_empty_table,
     Builder::default()
         .build()
-        .with(Highlight::outline(Segment::all(), '+')),
+        .with(Highlight::new(Segment::all(), Border::filled('+'))),
     ""
 );
 
@@ -38,8 +38,8 @@ test_table!(
     highlingt_cell,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::outline(Cell::new(0, 0), '+'))
-        .with(Highlight::outline(Cell::new(1, 1), '*')),
+        .with(Highlight::new(Cell::new(0, 0), Border::filled('+')))
+        .with(Highlight::new(Cell::new(1, 1), Border::filled('*'))),
     "+++++──────────┬──────────┬──────────┐"
     "+ N + column 0 │ column 1 │ column 2 │"
     "++++************──────────┼──────────┤"
@@ -55,8 +55,8 @@ test_table!(
     highlingt_row,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::outline(Rows::single(0), '+'))
-        .with(Highlight::outline(Rows::single(3), '*')),
+        .with(Highlight::new(Rows::single(0), Border::filled('+')))
+        .with(Highlight::new(Rows::single(3), Border::filled('*'))),
     "++++++++++++++++++++++++++++++++++++++"
     "+ N │ column 0 │ column 1 │ column 2 +"
     "++++++++++++++++++++++++++++++++++++++"
@@ -72,8 +72,8 @@ test_table!(
     highlingt_column,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::new(Columns::single(0)).border(Border::filled('+')))
-        .with(Highlight::new(Columns::single(2)).border(Border::filled('*'))),
+        .with(Highlight::new(Columns::single(0), Border::filled('+')))
+        .with(Highlight::new(Columns::single(2), Border::filled('*'))),
     "+++++──────────************──────────┐"
     "+ N + column 0 * column 1 * column 2 │"
     "+───+──────────*──────────*──────────┤"
@@ -89,7 +89,7 @@ test_table!(
     highlingt_row_range,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::outline(Rows::new(1..3), '+')),
+        .with(Highlight::new(Rows::new(1..3), Border::filled('+'))),
     "┌───┬──────────┬──────────┬──────────┐"
     "│ N │ column 0 │ column 1 │ column 2 │"
     "++++++++++++++++++++++++++++++++++++++"
@@ -105,7 +105,7 @@ test_table!(
     highlingt_column_range,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::outline(Columns::new(..2), '+')),
+        .with(Highlight::new(Columns::new(..2), Border::filled('+'))),
     "++++++++++++++++──────────┬──────────┐"
     "+ N │ column 0 + column 1 │ column 2 │"
     "+───┼──────────+──────────┼──────────┤"
@@ -121,7 +121,8 @@ test_table!(
     highlingt_frame,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::new(Frame).border(
+        .with(Highlight::new(
+            Frame,
             Border::filled('+')
                 .set_corner_top_left('*')
                 .set_corner_top_right('#')
@@ -143,7 +144,8 @@ test_table!(
     highlingt_full,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::new(Segment::all()).border(
+        .with(Highlight::new(
+            Segment::all(),
             Border::filled('+')
                 .set_corner_top_left('*')
                 .set_corner_top_right('#')
@@ -165,8 +167,8 @@ test_table!(
     highlingt_single_column,
     Matrix::table(3, 0)
         .with(Style::modern())
-        .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'))),
+        .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'))),
     "┌xxx┐"
     "* N │"
     "├───┤"
@@ -182,9 +184,9 @@ test_table!(
     highlingt_several_times,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::outline(Frame, '*'))
-        .with(Highlight::outline(Cell::new(1, 1), '#'))
-        .with(Highlight::outline(Columns::single(3), 'x')),
+        .with(Highlight::new(Frame, Border::filled('*')))
+        .with(Highlight::new(Cell::new(1, 1), Border::filled('#')))
+        .with(Highlight::new(Columns::single(3), Border::filled('x'))),
     "**************************xxxxxxxxxxxx"
     "* N │ column 0 │ column 1 x column 2 x"
     "*───############──────────x──────────x"
@@ -231,7 +233,7 @@ fn highlingt_complex_figures() {
 
             let table = Matrix::new(3, 3)
                 .with(Style::modern())
-                .with(Highlight::new($object).border(border))
+                .with(Highlight::new($object, border))
                 .to_string();
 
             assert_eq!(table, $expected);
diff --git a/tabled/tests/settings/rotate_test.rs b/tabled/tests/settings/rotate_test.rs
index 477a695..2d906f1 100644
--- a/tabled/tests/settings/rotate_test.rs
+++ b/tabled/tests/settings/rotate_test.rs
@@ -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(Border::new().set_top('*')))
+        .with(Highlight::new(Rows::single(0), Border::new().set_top('*')))
         .with(Rotate::Left),
     "+*****************+-----+"
     "| i32 | 789 | 891 | 333 |"
@@ -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(Border::new().set_bottom('*')))
+        .with(Highlight::new(Cell::new(0, 2), Border::new().set_bottom('*')))
         .with(Rotate::Left),
         "+-----+-----+-----+-----+"
         "| i32 | 789 | 891 | 333 |"
diff --git a/tabled/tests/settings/style_test.rs b/tabled/tests/settings/style_test.rs
index ae3fbb7..0370952 100644
--- a/tabled/tests/settings/style_test.rs
+++ b/tabled/tests/settings/style_test.rs
@@ -254,18 +254,6 @@ test_table!(
     "| N | column 0 | column 1 |"
     "+---+----------+----------+"
     "| 0 |   0-0    |   0-1    |"
-    "-Table---------+----------+"
-    "| 1 |   1-0    |   1-1    |"
-    "+---+----------+----------+"
-);
-
-test_table!(
-    top_border_override_last_1_test,
-    Matrix::table(2, 2).with(LineText::new("-Table", Rows::last() + 1)),
-    "+---+----------+----------+"
-    "| N | column 0 | column 1 |"
-    "+---+----------+----------+"
-    "| 0 |   0-0    |   0-1    |"
     "+---+----------+----------+"
     "| 1 |   1-0    |   1-1    |"
     "-Table---------+----------+"
@@ -549,7 +537,7 @@ test_table!(
 
 test_table!(
     style_frame_test_0,
-    Matrix::table(2, 2).with(Highlight::new(Rows::single(1)).border(Border::inherit(Style::modern()))),
+    Matrix::table(2, 2).with(Highlight::new(Rows::single(1), Border::inherit(Style::modern()))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "┌─────────────────────────┐"
@@ -563,8 +551,8 @@ test_table!(
     style_frame_test_1,
     Matrix::table(2, 2)
         .with(Style::blank())
-        .with(Highlight::new(Rows::single(0)).border(Border::inherit(Style::extended())))
-        .with(Highlight::new(Rows::single(2)).border(Border::inherit(Style::extended()))),
+        .with(Highlight::new(Rows::single(0), Border::inherit(Style::extended())))
+        .with(Highlight::new(Rows::single(2), Border::inherit(Style::extended()))),
     "╔═════════════════════════╗"
     "║ N   column 0   column 1 ║"
     "╚═════════════════════════╝"