Repository: zhiburt/tabled
Pull request #369 (2023-11-02 19:56:24)

tabled/ Rethinking Style::* components
close #366 (continuation)


Patch:
diff --git a/papergrid/src/config/border.rs b/papergrid/src/config/border.rs
index e803900..0836bd5 100644
--- a/papergrid/src/config/border.rs
+++ b/papergrid/src/config/border.rs
@@ -59,6 +59,20 @@ impl<T> Border<T> {
         }
     }
 
+    /// This function constructs a cell borders with all sides being empty (set off).
+    pub const fn empty() -> Self {
+        Self {
+            top: None,
+            bottom: None,
+            right: None,
+            right_top_corner: None,
+            right_bottom_corner: None,
+            left: None,
+            left_bottom_corner: None,
+            left_top_corner: None,
+        }
+    }
+
     /// Checks whether any side is set.
     pub const fn is_empty(&self) -> bool {
         self.top.is_none()
@@ -106,9 +120,7 @@ impl<T: Copy> Border<T> {
 }
 
 impl<T: Copy> Border<&T> {
-    /// This function constructs a cell borders with all sides's char set to a given character.
-    ///
-    /// It behaves like [`Border::full`] with the same character set to each side.
+    /// Copies the underlying reference to a new border.
     pub fn copied(&self) -> Border<T> {
         Border {
             top: self.top.copied(),
@@ -124,9 +136,7 @@ impl<T: Copy> Border<&T> {
 }
 
 impl<T: Clone> Border<&T> {
-    /// This function constructs a cell borders with all sides's char set to a given character.
-    ///
-    /// It behaves like [`Border::full`] with the same character set to each side.
+    /// Copies the underlying reference to a new border.
     pub fn cloned(&self) -> Border<T> {
         Border {
             top: self.top.cloned(),
@@ -140,3 +150,31 @@ impl<T: Clone> Border<&T> {
         }
     }
 }
+
+impl<T> Border<T> {
+    /// Convert all values on the border into another ones.
+    pub fn convert<B>(self) -> Border<B>
+    where
+        B: From<T>,
+    {
+        macro_rules! conv_opt {
+            ($opt:expr) => {
+                match $opt {
+                    Some(opt) => Some(B::from(opt)),
+                    None => None,
+                }
+            };
+        }
+
+        Border {
+            top: conv_opt!(self.top),
+            bottom: conv_opt!(self.bottom),
+            left: conv_opt!(self.left),
+            right: conv_opt!(self.right),
+            left_bottom_corner: conv_opt!(self.left_bottom_corner),
+            left_top_corner: conv_opt!(self.left_top_corner),
+            right_bottom_corner: conv_opt!(self.right_bottom_corner),
+            right_top_corner: conv_opt!(self.right_top_corner),
+        }
+    }
+}
diff --git a/papergrid/src/config/borders.rs b/papergrid/src/config/borders.rs
index d242e1f..cfe5b4c 100644
--- a/papergrid/src/config/borders.rs
+++ b/papergrid/src/config/borders.rs
@@ -1,5 +1,5 @@
 /// Borders represents a Table frame with horizontal and vertical split lines.
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Borders<T> {
     /// A top horizontal on the frame.
     pub top: Option<T>,
diff --git a/papergrid/src/config/line.rs b/papergrid/src/config/line.rs
index c3089e1..4615332 100644
--- a/papergrid/src/config/line.rs
+++ b/papergrid/src/config/line.rs
@@ -1,5 +1,5 @@
 /// A line data structure.
-#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Line<T> {
     /// A horizontal/vertical character.
     pub main: T,
diff --git a/papergrid/src/config/spanned/borders_config.rs b/papergrid/src/config/spanned/borders_config.rs
index fe77298..fb61ed3 100644
--- a/papergrid/src/config/spanned/borders_config.rs
+++ b/papergrid/src/config/spanned/borders_config.rs
@@ -12,8 +12,13 @@ pub(crate) struct BordersConfig<T> {
     layout: BordersLayout,
 }
 
-impl<T: std::fmt::Debug> BordersConfig<T> {
-    pub(crate) fn insert_border(&mut self, pos: Position, border: Border<T>) {
+impl<T> BordersConfig<T> {
+    pub(crate) fn insert_border(&mut self, pos: Position, border: Border<T>)
+    where
+        T: std::fmt::Debug,
+    {
+        dbg!("{:?}", &border);
+
         if let Some(c) = border.top {
             self.cells.horizontal.insert(pos, c);
             self.layout.horizontals.insert(pos.0);
@@ -114,10 +119,6 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
             self.layout.right = true;
         }
 
-        if line.intersection.is_some() {
-            self.layout.inner_verticals = true;
-        }
-
         self.horizontals.insert(row, line);
         self.layout.horizontals.insert(row);
     }
@@ -126,6 +127,13 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
         self.horizontals.get(&row)
     }
 
+    pub(crate) fn get_horizontal_lines(&self) -> HashMap<usize, HorizontalLine<T>>
+    where
+        T: Clone,
+    {
+        self.horizontals.clone()
+    }
+
     pub(crate) fn remove_horizontal_line(&mut self, row: usize, count_rows: usize) {
         self.horizontals.remove(&row);
         self.layout.horizontals.remove(&row);
@@ -135,7 +143,7 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
         }
     }
 
-    pub(crate) fn insert_vertical_line(&mut self, row: usize, line: VerticalLine<T>) {
+    pub(crate) fn insert_vertical_line(&mut self, column: usize, line: VerticalLine<T>) {
         if line.top.is_some() {
             self.layout.top = true;
         }
@@ -144,12 +152,19 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
             self.layout.bottom = true;
         }
 
-        self.verticals.insert(row, line);
-        self.layout.verticals.insert(row);
+        self.verticals.insert(column, line);
+        self.layout.verticals.insert(column);
     }
 
-    pub(crate) fn get_vertical_line(&self, row: usize) -> Option<&VerticalLine<T>> {
-        self.verticals.get(&row)
+    pub(crate) fn get_vertical_line(&self, column: usize) -> Option<&VerticalLine<T>> {
+        self.verticals.get(&column)
+    }
+
+    pub(crate) fn get_vertical_lines(&self) -> HashMap<usize, VerticalLine<T>>
+    where
+        T: Clone,
+    {
+        self.verticals.clone()
     }
 
     pub(crate) fn remove_vertical_line(&mut self, col: usize, count_columns: usize) {
@@ -221,11 +236,12 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
         let use_left = pos.1 == 0;
         let use_right = pos.1 == count_cols;
 
-        if let Some(c) = self.cells.intersection.get(&pos) {
-            return Some(c);
+        let itersection = self.cells.intersection.get(&pos);
+        if itersection.is_some() {
+            return itersection;
         }
 
-        let hl_c = self.horizontals.get(&pos.0).and_then(|l| {
+        let itersection = self.horizontals.get(&pos.0).and_then(|l| {
             if use_left && l.left.is_some() {
                 l.left.as_ref()
             } else if use_right && l.right.is_some() {
@@ -236,12 +252,11 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
                 None
             }
         });
-
-        if let Some(c) = hl_c {
-            return Some(c);
+        if itersection.is_some() {
+            return itersection;
         }
 
-        let vl_c = self.verticals.get(&pos.1).and_then(|l| {
+        let itersection = self.verticals.get(&pos.1).and_then(|l| {
             if use_top && l.top.is_some() {
                 l.top.as_ref()
             } else if use_bottom && l.bottom.is_some() {
@@ -252,12 +267,11 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
                 None
             }
         });
-
-        if let Some(c) = vl_c {
-            return Some(c);
+        if itersection.is_some() {
+            return itersection;
         }
 
-        let borders_c = {
+        let itersection = {
             if use_top && use_left {
                 self.borders.top_left.as_ref()
             } else if use_top && use_right {
@@ -278,9 +292,8 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
                 self.borders.intersection.as_ref()
             }
         };
-
-        if let Some(c) = borders_c {
-            return Some(c);
+        if itersection.is_some() {
+            return itersection;
         }
 
         self.global.as_ref()
@@ -305,21 +318,18 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
     fn is_horizontal_set(&self, row: usize, count_rows: usize) -> bool {
         (row == 0 && self.layout.top)
             || (row == count_rows && self.layout.bottom)
-            || (row > 0 && row < count_rows && self.layout.inner_horizontals)
             || self.layout.horizontals.contains(&row)
     }
 
     fn is_vertical_set(&self, col: usize, count_cols: usize) -> bool {
         (col == 0 && self.layout.left)
             || (col == count_cols && self.layout.right)
-            || (col > 0 && col < count_cols && self.layout.inner_verticals)
             || self.layout.verticals.contains(&col)
     }
 
     fn check_is_horizontal_set(&self, row: usize, count_rows: usize) -> bool {
         (row == 0 && self.layout.top)
             || (row == count_rows && self.layout.bottom)
-            || (row > 0 && row < count_rows && self.layout.inner_horizontals)
             || self.cells.horizontal.keys().any(|&p| p.0 == row)
             || self.cells.intersection.keys().any(|&p| p.0 == row)
     }
@@ -327,7 +337,6 @@ impl<T: std::fmt::Debug> BordersConfig<T> {
     fn check_is_vertical_set(&self, col: usize, count_cols: usize) -> bool {
         (col == 0 && self.layout.left)
             || (col == count_cols && self.layout.right)
-            || (col > 0 && col < count_cols && self.layout.inner_verticals)
             || self.cells.vertical.keys().any(|&p| p.1 == col)
             || self.cells.intersection.keys().any(|&p| p.1 == col)
     }
@@ -346,8 +355,6 @@ pub(crate) struct BordersLayout {
     right: bool,
     top: bool,
     bottom: bool,
-    inner_verticals: bool,
-    inner_horizontals: bool,
     horizontals: HashSet<usize>,
     verticals: HashSet<usize>,
 }
diff --git a/papergrid/src/config/spanned/mod.rs b/papergrid/src/config/spanned/mod.rs
index a7f71e1..66b1d44 100644
--- a/papergrid/src/config/spanned/mod.rs
+++ b/papergrid/src/config/spanned/mod.rs
@@ -173,6 +173,14 @@ impl SpannedConfig {
         self.borders.get_vertical_line(line)
     }
 
+    /// Gets all overridden vertical lines.
+    ///
+    /// Row `0` means the top row.
+    /// Row `grid.count_rows()` means the bottom row.
+    pub fn get_vertical_lines(&self) -> HashMap<usize, VerticalLine> {
+        self.borders.get_vertical_lines()
+    }
+
     /// Set the border line by column index.
     ///
     /// Row `0` means the left row.
@@ -197,6 +205,14 @@ impl SpannedConfig {
         self.borders.get_horizontal_line(line)
     }
 
+    /// Gets all overridden lines.
+    ///
+    /// Row `0` means the top row.
+    /// Row `grid.count_rows()` means the bottom row.
+    pub fn get_horizontal_lines(&self) -> HashMap<usize, HorizontalLine> {
+        self.borders.get_horizontal_lines()
+    }
+
     /// Override a character on a horizontal line.
     ///
     /// If borders are not set the char won't be used.
diff --git a/papergrid/src/grid/iterable.rs b/papergrid/src/grid/iterable.rs
index 4bb80b0..67b7108 100644
--- a/papergrid/src/grid/iterable.rs
+++ b/papergrid/src/grid/iterable.rs
@@ -551,6 +551,10 @@ fn print_vertical_intersection<'a, F: fmt::Write>(
     shape: (usize, usize),
     used_color: &mut Option<&'a AnsiColor<'static>>,
 ) -> fmt::Result {
+    if !cfg.has_vertical(pos.1, shape.1) {
+        return Ok(());
+    }
+
     match cfg.get_intersection(pos, shape) {
         Some(c) => {
             let clr = cfg.get_intersection_color(pos, shape);
diff --git a/papergrid/src/grid/peekable.rs b/papergrid/src/grid/peekable.rs
index ee78772..aed568b 100644
--- a/papergrid/src/grid/peekable.rs
+++ b/papergrid/src/grid/peekable.rs
@@ -220,14 +220,23 @@ fn print_vertical_intersection<'a, F: fmt::Write>(
     shape: (usize, usize),
     used_color: &mut Option<&'a AnsiColor<'static>>,
 ) -> fmt::Result {
-    match cfg.get_intersection(pos, shape) {
-        Some(c) => {
-            let clr = cfg.get_intersection_color(pos, shape);
-            prepare_coloring(f, clr, used_color)?;
-            f.write_char(c)
-        }
-        None => Ok(()),
+    let intersection = match cfg.get_intersection(pos, shape) {
+        Some(c) => c,
+        None => return Ok(()),
+    };
+
+    // We need to make sure that we need to print it.
+    // Specifically for cases where we have a limited amount of verticals.
+    //
+    // todo: Yes... this check very likely degrages performance a bit,
+    //       Surely we need to rethink it.
+    if !cfg.has_vertical(pos.1, shape.1) {
+        return Ok(());
     }
+
+    let color = cfg.get_intersection_color(pos, shape);
+    prepare_coloring(f, color, used_color)?;
+    f.write_char(intersection)
 }
 
 fn prepare_coloring<'a, 'b, F: Write>(
diff --git a/tabled/Cargo.toml b/tabled/Cargo.toml
index 95b6d3e..4997504 100644
--- a/tabled/Cargo.toml
+++ b/tabled/Cargo.toml
@@ -274,6 +274,12 @@ name = "target_content"
 path = "examples/target_content.rs"
 required-features = ["std", "derive"]
 
+[[example]]
+name = "style_modern_rounded"
+path = "examples/style_modern_rounded.rs"
+required-features = ["std"]
+
+
 [features]
 default = ["derive", "macros"]
 std = ["papergrid/std"]
@@ -282,7 +288,7 @@ color = ["papergrid/color", "ansi-str", "ansitok", "std"]
 macros = ["std"]
 
 [dependencies]
-papergrid = { version = "0.10", default-features = false }
+papergrid = { path = "../papergrid", version = "0.10", default-features = false }
 tabled_derive = { path = "../tabled_derive", version = "0.6", optional = true }
 ansi-str = { version = "0.8", optional = true }
 ansitok = { version = "0.2", optional = true }
diff --git a/tabled/examples/border_text.rs b/tabled/examples/border_text.rs
index bbdb767..633f9d3 100644
--- a/tabled/examples/border_text.rs
+++ b/tabled/examples/border_text.rs
@@ -21,7 +21,7 @@
 use tabled::{
     settings::{
         object::Rows,
-        style::{BorderText, HorizontalLine, Style},
+        style::{LineText, Style},
     },
     Table,
 };
@@ -31,13 +31,16 @@ fn main() {
 
     let table = Table::new(data)
         .with(
-            Style::modern()
-                .remove_horizontal()
-                .horizontals([HorizontalLine::new(1, Style::modern().get_horizontal())]),
+            Style::modern().remove_horizontal().horizontals([(
+                1,
+                Style::modern()
+                    .get_horizontal_line()
+                    .left(Style::modern().get_frame().get_left()),
+            )]),
         )
-        .with(BorderText::new(" Numbers ").horizontal(Rows::first()))
-        .with(BorderText::new(" More numbers ").horizontal(1))
-        .with(BorderText::new(" end. ").horizontal(Rows::last()))
+        .with(LineText::new("Numbers").horizontal(Rows::first()).offset(1))
+        .with(LineText::new("More numbers").horizontal(1).offset(1))
+        .with(LineText::new("end.").horizontal(Rows::last()).offset(1))
         .to_string();
 
     println!("{table}");
diff --git a/tabled/examples/color.rs b/tabled/examples/color.rs
index b7064b3..32aaf05 100644
--- a/tabled/examples/color.rs
+++ b/tabled/examples/color.rs
@@ -54,18 +54,18 @@ fn main() {
 
     let yellow_color = Color::try_from(' '.yellow().to_string()).unwrap();
 
-    let first_row_style = Modify::new(Rows::first()).with(
-        BorderColor::default()
-            .bottom(color_red)
-            .corner_bottom_left(color_purple.clone())
-            .corner_bottom_right(color_purple),
-    );
+    let border = BorderColor::new()
+        .set_bottom(color_red)
+        .set_left(Color::default())
+        .set_right(Color::default())
+        .set_corner_bottom_left(color_purple.clone())
+        .set_corner_bottom_right(color_purple);
 
     let mut table = Table::new(data);
     table
         .with(Style::psql())
         .with(yellow_color)
-        .with(first_row_style)
+        .modify(Rows::first(), border)
         .with(Modify::new(Columns::single(0)).with(red))
         .with(Modify::new(Columns::single(1)).with(green))
         .with(Modify::new(Columns::single(2)).with(blue));
diff --git a/tabled/examples/custom_style.rs b/tabled/examples/custom_style.rs
index e6f0848..5f28a91 100644
--- a/tabled/examples/custom_style.rs
+++ b/tabled/examples/custom_style.rs
@@ -8,10 +8,7 @@
 //! number of functional columns and rows.
 
 use tabled::{
-    settings::{
-        style::{HorizontalLine, Style, VerticalLine},
-        Alignment,
-    },
+    settings::{style::Style, Alignment},
     Table, Tabled,
 };
 
@@ -42,10 +39,10 @@ fn main() {
     ];
 
     let theme = Style::modern()
+        .horizontals([(1, Style::modern().get_horizontal_line())])
+        .verticals([(1, Style::modern().get_vertical_line())])
         .remove_horizontal()
-        .remove_vertical()
-        .horizontals([HorizontalLine::new(1, Style::modern().get_horizontal()).intersection(None)])
-        .verticals([VerticalLine::new(1, Style::modern().get_vertical())]);
+        .remove_vertical();
 
     let mut table = Table::new(data);
     table.with(theme).with(Alignment::left());
diff --git a/tabled/examples/disable.rs b/tabled/examples/disable.rs
index 9f82449..a9cade3 100644
--- a/tabled/examples/disable.rs
+++ b/tabled/examples/disable.rs
@@ -8,7 +8,7 @@ use tabled::{
     settings::{
         location::ByColumnName,
         style::{Border, Style},
-        Disable, Modify,
+        Disable,
     },
     Table, Tabled,
 };
@@ -43,7 +43,7 @@ fn main() {
     table
         .with(Style::markdown())
         .with(Disable::column(ByColumnName::new("is_active")))
-        .with(Modify::new(ByColumnName::new("name")).with(Border::filled('#')));
+        .modify(ByColumnName::new("name"), Border::filled('#'));
 
     println!("{table}");
 }
diff --git a/tabled/examples/highlight.rs b/tabled/examples/highlight.rs
index 0b6abb8..c99b7ff 100644
--- a/tabled/examples/highlight.rs
+++ b/tabled/examples/highlight.rs
@@ -7,7 +7,7 @@
 use tabled::{
     settings::{
         object::{Columns, Object, Rows},
-        style::{Border, Style},
+        style::Style,
         Highlight,
     },
     Table,
@@ -18,9 +18,9 @@ fn main() {
 
     let table = Table::new(data)
         .with(Style::modern())
-        .with(Highlight::new(
+        .with(Highlight::outline(
             Rows::first().and(Columns::single(1)),
-            Border::filled('*'),
+            '*',
         ))
         .to_string();
 
diff --git a/tabled/examples/highlight_color.rs b/tabled/examples/highlight_color.rs
index 4646f38..8cdd153 100644
--- a/tabled/examples/highlight_color.rs
+++ b/tabled/examples/highlight_color.rs
@@ -17,7 +17,7 @@ fn main() {
 
     let table = Table::new(data)
         .with(Style::modern())
-        .with(Highlight::colored(
+        .with(Highlight::color(
             Rows::first().and(Columns::single(1)),
             BorderColor::filled(Color::BG_BRIGHT_BLACK),
         ))
diff --git a/tabled/examples/merge_duplicates_2.rs b/tabled/examples/merge_duplicates_2.rs
index 063664d..574a2e8 100644
--- a/tabled/examples/merge_duplicates_2.rs
+++ b/tabled/examples/merge_duplicates_2.rs
@@ -7,11 +7,7 @@
 //! * Merge supports both [`Merge::vertical()`] and [`Merge::horizontal()`].
 
 use tabled::{
-    settings::{
-        object::{Cell, Columns, Object, Rows},
-        style::{Border, BorderSpanCorrection, Style},
-        Merge, Modify,
-    },
+    settings::{style::Style, Merge},
     Table, Tabled,
 };
 
@@ -29,7 +25,7 @@ fn main() {
 
     let mut table = Table::builder(data).index().transpose().build();
     config_theme(&mut table);
-    table.with(Merge::horizontal()).with(BorderSpanCorrection);
+    table.with(Merge::horizontal());
 
     println!("{table}");
 }
@@ -61,18 +57,12 @@ impl DatabaseTable {
 }
 
 fn config_theme(table: &mut Table) {
-    table
-        .with(Style::rounded().remove_vertical())
-        .with(Modify::new(Columns::first()).with(Border::default().right('│')))
-        .with(
-            Modify::new(Cell::new(0, 0)).with(
-                Border::default()
-                    .corner_top_right('┬')
-                    .corner_bottom_right('┼'),
-            ),
-        )
-        .with(
-            Modify::new(Columns::first().intersect(Rows::last()))
-                .with(Border::default().corner_bottom_right('┴')),
-        );
+    let style = Style::modern()
+        .frame(Style::rounded().get_frame())
+        .horizontals([(1, Style::modern().get_horizontal_line())])
+        .verticals([(1, Style::modern().get_vertical_line())])
+        .remove_horizontal()
+        .remove_vertical();
+
+    table.with(style);
 }
diff --git a/tabled/examples/nested_table.rs b/tabled/examples/nested_table.rs
index 8884c81..7084456 100644
--- a/tabled/examples/nested_table.rs
+++ b/tabled/examples/nested_table.rs
@@ -13,7 +13,7 @@ use tabled::{
     builder::Builder,
     settings::{
         object::{Rows, Segment},
-        style::{HorizontalLine, Style},
+        style::Style,
         Alignment, Modify, Padding, Width,
     },
     Table,
@@ -72,7 +72,7 @@ fn create_class(name: &str, fields: &[(&str, &str, &str)], methods: &[&str]) ->
     table
         .with(
             Style::ascii()
-                .horizontals([HorizontalLine::new(1, Style::ascii().get_horizontal())])
+                .horizontals([(1, Style::ascii().get_horizontal_line())])
                 .remove_horizontal()
                 .remove_vertical(),
         )
diff --git a/tabled/examples/nested_table_3.rs b/tabled/examples/nested_table_3.rs
index 8e79b27..19b037d 100644
--- a/tabled/examples/nested_table_3.rs
+++ b/tabled/examples/nested_table_3.rs
@@ -50,7 +50,7 @@ fn main() {
         .with(Extract::rows(1..))
         .with(Style::ascii().remove_horizontal())
         .with(Modify::new(Segment::all()).with(Alignment::center()))
-        .with(Highlight::new(Cell::new(0, 0), Border::filled('*')));
+        .with(Highlight::border(Cell::new(0, 0), Border::filled('*')));
 
     println!("{a_welcome_table}");
 }
diff --git a/tabled/examples/shadow.rs b/tabled/examples/shadow.rs
index baa856e..b593996 100644
--- a/tabled/examples/shadow.rs
+++ b/tabled/examples/shadow.rs
@@ -1,6 +1,6 @@
 //! This example can be run with the following command:
 //!
-//! `echo -e -n 'Some text\nIn the box' | cargo run --example shadow`
+//! `cargo run --example shadow -- "Some text" "In the box"`
 //!
 //! This example demonstrates using the [`Shadow`] [`TableOption`] to create
 //! a striking frame around a [`Table`] display.
@@ -14,7 +14,7 @@
 //!
 //! * 🎉 Inspired by <https://en.wikipedia.org/wiki/Box-drawing_character>
 
-use std::{io::Read, iter::FromIterator};
+use std::iter::FromIterator;
 
 use tabled::{
     builder::Builder,
@@ -22,7 +22,7 @@ use tabled::{
     row,
     settings::{
         object::Cell,
-        style::{BorderChar, Offset, RawStyle, Style},
+        style::{LineChar, RawStyle, Style},
         Height, Modify, Padding, Shadow, Width,
     },
     Table,
@@ -42,8 +42,21 @@ fn print_table(message: String) {
 }
 
 fn read_message() -> String {
+    let args = std::env::args().collect::<Vec<_>>();
+
+    if args.len() < 2 {
+        eprintln!("Expected to get at least 1 argument to be printed");
+        std::process::exit(-1);
+    }
+
     let mut buf = String::new();
-    std::io::stdin().read_to_string(&mut buf).unwrap();
+    for (i, text) in args.iter().skip(1).enumerate() {
+        if i > 0 {
+            buf.push('\n');
+        }
+
+        buf.push_str(text);
+    }
 
     buf
 }
@@ -115,29 +128,28 @@ fn create_small_table(style: RawStyle) -> Table {
     table
 }
 
+// todo: very likely can be simplified
 fn create_main_table(message: &str) -> Table {
     let (count_lines, message_width) = string::string_dimension(message);
     let count_additional_separators = if count_lines > 2 { count_lines - 2 } else { 0 };
+    let left_table_space = (0..count_additional_separators)
+        .map(|_| "    ║   \n")
+        .collect::<String>();
 
     let left_table = format!(
         "  ╔═══╗ \n  ╚═╦═╝ \n{}═╤══╩══╤\n ├──┬──┤\n └──┴──┘",
-        (0..count_additional_separators)
-            .map(|_| "    ║   \n")
-            .collect::<String>()
+        left_table_space
     );
 
-    let message = if count_lines < 2 {
+    let mut message = message.to_owned();
+    if count_lines < 2 {
         let mut i = count_lines;
-        let mut buf = message.to_string();
         while i < 2 {
-            buf.push('\n');
+            message.push('\n');
             i += 1;
         }
+    }
 
-        buf
-    } else {
-        message.to_owned()
-    };
     let count_lines = count_lines.max(2);
 
     let message = format!("{}\n{}", message, "═".repeat(message_width));
@@ -146,14 +158,8 @@ fn create_main_table(message: &str) -> Table {
     table
         .with(Padding::zero())
         .with(Style::modern().remove_vertical())
-        .with(
-            Modify::new(Cell::new(0, 0))
-                .with(BorderChar::vertical('╞', Offset::Begin(count_lines))),
-        )
-        .with(
-            Modify::new(Cell::new(0, 2))
-                .with(BorderChar::vertical('╡', Offset::Begin(count_lines))),
-        )
+        .with(Modify::new(Cell::new(0, 0)).with(LineChar::vertical('╞', count_lines)))
+        .with(Modify::new(Cell::new(0, 2)).with(LineChar::vertical('╡', count_lines)))
         .with(Shadow::new(2));
 
     table
diff --git a/tabled/examples/style_modern_rounded.rs b/tabled/examples/style_modern_rounded.rs
new file mode 100644
index 0000000..d3e7b7b
--- /dev/null
+++ b/tabled/examples/style_modern_rounded.rs
@@ -0,0 +1,35 @@
+use tabled::{
+    settings::{
+        style::{On, RawStyle},
+        Style,
+    },
+    Table,
+};
+
+type FullStyle = Style<On, On, On, On, On, On>;
+
+const STYLE_1: FullStyle = Style::modern().frame(Style::rounded().get_frame());
+
+const STYLE_2: FullStyle = Style::rounded()
+    .horizontal_line(Style::modern().get_horizontal_line())
+    .remove_horizontals();
+
+fn main() {
+    assert_eq!(RawStyle::from(STYLE_1), RawStyle::from(STYLE_2));
+
+    let data = vec![("Hello", "world", "!"); 5];
+
+    let mut table = Table::new(&data);
+    table.with(STYLE_2);
+
+    let output = table.to_string();
+
+    println!("{output}");
+
+    let mut table = Table::new(&data);
+    table.with(STYLE_1);
+
+    let output = table.to_string();
+
+    println!("{output}");
+}
diff --git a/tabled/examples/target_content.rs b/tabled/examples/target_content.rs
index fcbea2a..452b1ee 100644
--- a/tabled/examples/target_content.rs
+++ b/tabled/examples/target_content.rs
@@ -1,10 +1,4 @@
-//! This example demonstrates using the [`Color`] [setting](tabled::settings) to
-//! stylize text, backgrounds, and borders.
-//!
-//! * 🚩 This example requires the `color` feature.
-//!
-//! * Note how [`Format::content()`] is used to break out [`CellOption`]
-//! specifications. This is helpful for organizing extensive [`Table`] configurations.
+//! This example demonstrates [`Locator`] usage to colorize certain cells.
 
 use tabled::{
     settings::{location::Locator, style::Style, Color},
diff --git a/tabled/src/settings/highlight/mod.rs b/tabled/src/settings/highlight/mod.rs
index 9428057..4083e5b 100644
--- a/tabled/src/settings/highlight/mod.rs
+++ b/tabled/src/settings/highlight/mod.rs
@@ -5,12 +5,14 @@
 
 use std::collections::HashSet;
 
+use papergrid::color::AnsiColor;
+
 use crate::{
     grid::{
         config::{Border as GridBorder, ColoredConfig, Entity, Position, SpannedConfig},
         records::{ExactRecords, Records},
     },
-    settings::{object::Object, style::BorderColor, Border, TableOption},
+    settings::{object::Object, style::BorderColor, Border, Color, TableOption},
 };
 
 /// Highlight modifies a table style by changing a border of a target [`Table`] segment.
@@ -31,7 +33,7 @@ use crate::{
 ///
 /// let table = Table::new(data.iter().enumerate())
 ///                .with(Style::markdown())
-///                .with(Highlight::new(Segment::all(), Border::default().top('^').bottom('v')))
+///                .with(Highlight::border(Segment::all(), Border::new().set_top('^').set_bottom('v')))
 ///                .to_string();
 ///
 /// assert_eq!(
@@ -67,7 +69,7 @@ use crate::{
 ///
 /// let table = Table::new(data.iter().enumerate())
 ///                .with(Style::markdown())
-///                .with(Highlight::new(Segment::all().not((0,0).and((1, 0)).and((0, 1)).and((0, 3))), Border::filled('*')))
+///                .with(Highlight::border(Segment::all().not((0,0).and((1, 0)).and((0, 1)).and((0, 3))), Border::filled('*')))
 ///                .to_string();
 ///
 /// println!("{}", table);
@@ -92,59 +94,84 @@ use crate::{
 #[derive(Debug)]
 pub struct Highlight<O> {
     target: O,
-    border: Border,
+    border: HighlightInner,
+}
+
+#[derive(Debug)]
+enum HighlightInner {
+    Border(GridBorder<char>),
+    // #[cfg(feature = "color")]
+    Color(GridBorder<AnsiColor<'static>>),
+    // #[cfg(feature = "color")]
+    ColoredBorder(GridBorder<char>, GridBorder<AnsiColor<'static>>),
 }
 
+// todo: Docs testss
+
+// todo: Move colors to Highlight itself
+// todo: Maybe add a default Border and set ask for a char -> Highlight::new(target).border().outline().color().outline_color()
+
 // todo: Add BorderColor.
 
 impl<O> Highlight<O> {
     /// Build a new instance of [`Highlight`]
     ///
     /// BE AWARE: if target exceeds boundaries it may panic.
-    pub fn new(target: O, border: Border) -> Self {
-        Self { target, border }
+    pub const fn border<T, B, L, R>(target: O, border: Border<T, B, L, R>) -> Self {
+        Self {
+            target,
+            border: HighlightInner::Border(border.into_inner()),
+        }
     }
-}
 
-impl<O> Highlight<O> {
-    /// Build a new instance of [`HighlightColored`]
-    pub fn colored(target: O, border: BorderColor) -> HighlightColored<O> {
-        HighlightColored { target, border }
+    /// Build a new instance of [`Highlight`]
+    ///
+    /// BE AWARE: if target exceeds boundaries it may panic.
+    // #[cfg(feature = "color")]
+    pub fn color<T, B, L, R>(target: O, border: BorderColor<T, B, L, R>) -> Self {
+        let color = border.into_inner();
+        let color = color.convert();
+
+        Self {
+            target,
+            border: HighlightInner::Color(color),
+        }
     }
-}
 
-impl<O, R, D> TableOption<R, D, ColoredConfig> for Highlight<O>
-where
-    O: Object<R>,
-    R: Records + ExactRecords,
-{
-    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        let count_rows = records.count_rows();
-        let count_cols = records.count_columns();
-
-        let cells = self.target.cells(records);
-        let segments = split_segments(cells, count_rows, count_cols);
-
-        for sector in segments {
-            set_border(cfg, &sector, self.border);
-        }
+    /// Build a new instance of [`Highlight`]
+    ///
+    /// BE AWARE: if target exceeds boundaries it may panic.
+    pub const fn outline(target: O, c: char) -> Self {
+        Self::border(target, Border::filled(c))
     }
 
-    fn hint_change(&self) -> Option<Entity> {
-        None
+    /// Build a new instance of [`Highlight`]
+    ///
+    /// BE AWARE: if target exceeds boundaries it may panic.
+    pub fn colored_outline<T, B, L, R>(target: O, c: char, color: Color) -> Self {
+        Self::colored_border(target, Border::filled(c), BorderColor::filled(color))
     }
-}
 
-/// A [`Highlight`] object which works with a [`BorderColored`]
-///
-/// [`BorderColored`]: crate::settings::style::BorderColor
-#[derive(Debug)]
-pub struct HighlightColored<O> {
-    target: O,
-    border: BorderColor,
+    /// Build a new instance of [`Highlight`]
+    ///
+    /// BE AWARE: if target exceeds boundaries it may panic.
+    // #[cfg(feature = "color")]
+    pub fn colored_border<T, B, L, R>(
+        target: O,
+        border: Border<T, B, L, R>,
+        color: BorderColor<T, B, L, R>,
+    ) -> Self {
+        let border = border.into_inner();
+        let color = color.into_inner().convert();
+
+        Self {
+            target,
+            border: HighlightInner::ColoredBorder(border, color),
+        }
+    }
 }
 
-impl<O, R, D> TableOption<R, D, ColoredConfig> for HighlightColored<O>
+impl<O, R, D> TableOption<R, D, ColoredConfig> for Highlight<O>
 where
     O: Object<R>,
     R: Records + ExactRecords,
@@ -156,8 +183,23 @@ where
         let cells = self.target.cells(records);
         let segments = split_segments(cells, count_rows, count_cols);
 
-        for sector in segments {
-            set_border_color(cfg, sector, &self.border);
+        match self.border {
+            HighlightInner::Border(border) => {
+                for sector in segments {
+                    set_border(cfg, &sector, border);
+                }
+            }
+            HighlightInner::Color(color) => {
+                for sector in segments {
+                    set_border_color(cfg, &sector, &color);
+                }
+            }
+            HighlightInner::ColoredBorder(border, color) => {
+                for sector in segments {
+                    set_border(cfg, &sector, border);
+                    set_border_color(cfg, &sector, &color);
+                }
+            }
         }
     }
 
@@ -168,15 +210,15 @@ where
 
 fn set_border_color(
     cfg: &mut SpannedConfig,
-    sector: HashSet<(usize, usize)>,
-    border: &BorderColor,
+    sector: &HashSet<(usize, usize)>,
+    border: &GridBorder<AnsiColor<'static>>,
 ) {
     if sector.is_empty() {
         return;
     }
-    let color = border.clone().into();
-    for &(row, col) in &sector {
-        let border = build_cell_border(&sector, (row, col), &color);
+    let color = border.clone();
+    for &(row, col) in sector {
+        let border = build_cell_border(sector, (row, col), &color);
         cfg.set_border_color((row, col), border);
     }
 }
@@ -261,12 +303,11 @@ fn is_segment_connected(
     false
 }
 
-fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<(usize, usize)>, border: Border) {
+fn set_border(cfg: &mut SpannedConfig, sector: &HashSet<(usize, usize)>, border: GridBorder<char>) {
     if sector.is_empty() {
         return;
     }
 
-    let border = border.into();
     for &pos in sector {
         let border = build_cell_border(sector, pos, &border);
         cfg.set_border(pos, border);
@@ -437,6 +478,31 @@ fn is_there_right_bottom_cell(sector: &HashSet<(usize, usize)>, row: usize, col:
     sector.contains(&(row + 1, col + 1))
 }
 
+// fn split_tuple_border<A, B>(border: GridBorder<(A, B)>) -> (GridBorder<A>, GridBorder<B>) {
+//     macro_rules! set_border {
+//         ($border1:expr, $border2:expr => $symbl:expr) => {
+//             if let Some((x1, x2)) = $symbl {
+//                 $border1 = Some(x1);
+//                 $border2 = Some(x2);
+//             }
+//         };
+//     }
+
+//     let mut a = GridBorder::empty();
+//     let mut b = GridBorder::empty();
+
+//     set_border!(a.bottom, b.bottom => border.bottom);
+//     set_border!(a.top, b.top => border.top);
+//     set_border!(a.left, b.left => border.left);
+//     set_border!(a.left_top_corner, b.left_top_corner => border.left_top_corner);
+//     set_border!(a.left_bottom_corner, b.left_bottom_corner => border.left_bottom_corner);
+//     set_border!(a.right, b.right => border.right);
+//     set_border!(a.right_top_corner, b.right_top_corner => border.right_top_corner);
+//     set_border!(a.right_bottom_corner, b.right_bottom_corner => border.right_bottom_corner);
+
+//     (a, b)
+// }
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/tabled/src/settings/style/border.rs b/tabled/src/settings/style/border.rs
index a8cbefb..d333f41 100644
--- a/tabled/src/settings/style/border.rs
+++ b/tabled/src/settings/style/border.rs
@@ -1,9 +1,11 @@
+use core::marker::PhantomData;
+
 use crate::{
     grid::{
-        config::{Border as GBorder, ColoredConfig, Entity},
+        config::{Border as GridBorder, ColoredConfig, Entity},
         records::{ExactRecords, Records},
     },
-    settings::CellOption,
+    settings::{style::On, CellOption},
 };
 
 /// Border represents a border of a Cell.
@@ -23,16 +25,41 @@ use crate::{
 /// ```
 ///
 /// ```rust,no_run
-/// # use tabled::{Table, settings::{Modify, style::{Style, Border}, object::Rows}};
+/// # use tabled::{Table, settings::{style::{Style, Border}, object::Rows}};
 /// # let data: Vec<&'static str> = Vec::new();
 /// let table = Table::new(&data)
 ///     .with(Style::ascii())
-///     .with(Modify::new(Rows::single(0)).with(Border::default().top('x')));
+///     .modify(Rows::single(0), Border::new().set_top('x'));
 /// ```
 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Border(GBorder<char>);
+pub struct Border<T, B, L, R> {
+    inner: GridBorder<char>,
+    _top: PhantomData<T>,
+    _bottom: PhantomData<B>,
+    _left: PhantomData<L>,
+    _right: PhantomData<R>,
+}
+
+impl<T, B, L, R> Border<T, B, L, R> {
+    pub(crate) const fn from_border(inner: GridBorder<char>) -> Border<T, B, L, R> {
+        Border {
+            inner,
+            _top: PhantomData,
+            _bottom: PhantomData,
+            _left: PhantomData,
+            _right: PhantomData,
+        }
+    }
+}
+
+impl Border<(), (), (), ()> {
+    /// Creates an empty border.
+    pub const fn new() -> Self {
+        Self::from_border(GridBorder::empty())
+    }
+}
 
-impl Border {
+impl Border<On, On, On, On> {
     /// This function constructs a cell borders with all sides set.
     #[allow(clippy::too_many_arguments)]
     pub const fn full(
@@ -45,7 +72,7 @@ impl Border {
         bottom_left: char,
         bottom_right: char,
     ) -> Self {
-        Self(GBorder::full(
+        Border::from_border(GridBorder::full(
             top,
             bottom,
             left,
@@ -67,57 +94,138 @@ impl Border {
     pub const fn empty() -> EmptyBorder {
         EmptyBorder
     }
+}
 
+impl<T, B, L, R> Border<T, B, L, R> {
     /// Set a top border character.
-    pub const fn top(mut self, c: char) -> Self {
-        self.0.top = Some(c);
-        self
+    pub const fn set_top(mut self, c: char) -> Border<On, B, L, R> {
+        self.inner.top = Some(c);
+        Border::from_border(self.inner)
     }
 
     /// Set a bottom border character.
-    pub const fn bottom(mut self, c: char) -> Self {
-        self.0.bottom = Some(c);
-        self
+    pub const fn set_bottom(mut self, c: char) -> Border<T, On, L, R> {
+        self.inner.bottom = Some(c);
+        Border::from_border(self.inner)
     }
 
     /// Set a left border character.
-    pub const fn left(mut self, c: char) -> Self {
-        self.0.left = Some(c);
-        self
+    pub const fn set_left(mut self, c: char) -> Border<T, B, On, R> {
+        self.inner.left = Some(c);
+        Border::from_border(self.inner)
     }
 
     /// Set a right border character.
-    pub const fn right(mut self, c: char) -> Self {
-        self.0.right = Some(c);
-        self
+    pub const fn set_right(mut self, c: char) -> Border<T, B, L, On> {
+        self.inner.right = Some(c);
+        Border::from_border(self.inner)
     }
 
+    /// Converts a border into a general data structure.
+    pub const fn into_inner(self) -> GridBorder<char> {
+        self.inner
+    }
+}
+
+impl<T, B, L> Border<T, B, L, On> {
+    /// Get a right character.
+    pub const fn get_right(&self) -> char {
+        get_char(self.inner.right)
+    }
+}
+
+impl<T, B, R> Border<T, B, On, R> {
+    /// Get a left character.
+    pub const fn get_left(&self) -> char {
+        get_char(self.inner.left)
+    }
+}
+
+impl<B, L, R> Border<On, B, L, R> {
+    /// Get a top character.
+    pub const fn get_top(&self) -> char {
+        get_char(self.inner.top)
+    }
+}
+
+impl<T, L, R> Border<T, On, L, R> {
+    /// Get a bottom character.
+    pub const fn get_bottom(&self) -> char {
+        get_char(self.inner.bottom)
+    }
+}
+
+impl<B, R> Border<On, B, On, R> {
     /// Set a top left intersection character.
-    pub const fn corner_top_left(mut self, c: char) -> Self {
-        self.0.left_top_corner = Some(c);
+    pub const fn set_corner_top_left(mut self, c: char) -> Self {
+        self.inner.left_top_corner = Some(c);
         self
     }
 
+    /// Get a top left intersection character.
+    pub const fn get_corner_top_left(&self) -> char {
+        get_char(self.inner.left_top_corner)
+    }
+}
+
+impl<B, L> Border<On, B, L, On> {
     /// Set a top right intersection character.
-    pub const fn corner_top_right(mut self, c: char) -> Self {
-        self.0.right_top_corner = Some(c);
+    pub const fn set_corner_top_right(mut self, c: char) -> Self {
+        self.inner.right_top_corner = Some(c);
         self
     }
 
+    /// Get a top right intersection character.
+    pub const fn get_corner_top_right(&self) -> char {
+        get_char(self.inner.right_top_corner)
+    }
+}
+
+impl<T, R> Border<T, On, On, R> {
     /// Set a bottom left intersection character.
-    pub const fn corner_bottom_left(mut self, c: char) -> Self {
-        self.0.left_bottom_corner = Some(c);
+    pub const fn set_corner_bottom_left(mut self, c: char) -> Self {
+        self.inner.left_bottom_corner = Some(c);
         self
     }
 
+    /// Get a bottom left intersection character.
+    pub const fn get_corner_bottom_left(&self) -> char {
+        get_char(self.inner.left_bottom_corner)
+    }
+}
+
+impl<T, L> Border<T, On, L, On> {
     /// Set a bottom right intersection character.
-    pub const fn corner_bottom_right(mut self, c: char) -> Self {
-        self.0.right_bottom_corner = Some(c);
+    pub const fn set_corner_bottom_right(mut self, c: char) -> Self {
+        self.inner.right_bottom_corner = Some(c);
         self
     }
+
+    /// Get a bottom left intersection character.
+    pub const fn get_corner_bottom_right(&self) -> char {
+        get_char(self.inner.right_bottom_corner)
+    }
+}
+
+impl<T, B, L, R> From<Border<T, B, L, R>> for GridBorder<char> {
+    fn from(value: Border<T, B, L, R>) -> Self {
+        value.inner
+    }
+}
+
+impl<T, B, L, R, Data> CellOption<Data, ColoredConfig> for Border<T, B, L, R>
+where
+    Data: Records + ExactRecords,
+{
+    fn change(self, records: &mut Data, cfg: &mut ColoredConfig, entity: Entity) {
+        CellOption::change(self.inner, records, cfg, entity)
+    }
 }
 
-impl<R> CellOption<R, ColoredConfig> for Border
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub struct EmptyBorder;
+
+impl<R> CellOption<R, ColoredConfig> for EmptyBorder
 where
     R: Records + ExactRecords,
 {
@@ -125,27 +233,19 @@ where
         let shape = (records.count_rows(), records.count_columns());
 
         for pos in entity.iter(shape.0, shape.1) {
-            cfg.set_border(pos, self.0);
+            cfg.remove_border(pos, shape);
         }
     }
 }
 
-impl From<GBorder<char>> for Border {
-    fn from(b: GBorder<char>) -> Border {
-        Border(b)
+const fn get_char(c: Option<char>) -> char {
+    match c {
+        Some(c) => c,
+        None => unreachable!(),
     }
 }
 
-impl From<Border> for GBorder<char> {
-    fn from(value: Border) -> Self {
-        value.0
-    }
-}
-
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct EmptyBorder;
-
-impl<R> CellOption<R, ColoredConfig> for EmptyBorder
+impl<R> CellOption<R, ColoredConfig> for GridBorder<char>
 where
     R: Records + ExactRecords,
 {
@@ -153,7 +253,7 @@ where
         let shape = (records.count_rows(), records.count_columns());
 
         for pos in entity.iter(shape.0, shape.1) {
-            cfg.remove_border(pos, shape);
+            cfg.set_border(pos, self);
         }
     }
 }
diff --git a/tabled/src/settings/style/border_color.rs b/tabled/src/settings/style/border_color.rs
index 6b3fa2b..162015b 100644
--- a/tabled/src/settings/style/border_color.rs
+++ b/tabled/src/settings/style/border_color.rs
@@ -1,32 +1,72 @@
 //! This module contains a configuration of a Border to set its color via [`BorderColor`].
 
+use core::marker::PhantomData;
+
 use crate::{
     grid::{
-        color::AnsiColor,
-        config::{Border, ColoredConfig, Entity},
+        config::{Border as GridBorder, ColoredConfig, Entity},
         records::{ExactRecords, Records},
     },
-    settings::{color::Color, CellOption, TableOption},
+    settings::{style::On, CellOption, Color, TableOption},
 };
 
-/// BorderColored represents a colored border of a Cell.
+/// Border represents a border color of a Cell.
+///
+/// ```text
+///                         top border
+///                             |
+///                             V
+/// corner top left ------> +_______+  <---- corner top left
+///                         |       |
+/// left border ----------> |  cell |  <---- right border
+///                         |       |
+/// corner bottom right --> +_______+  <---- corner bottom right
+///                             ^
+///                             |
+///                        bottom border
+/// ```
+///
+/// # Example
 ///
 /// ```rust,no_run
-/// # use tabled::{settings::{style::BorderColor, Style, Color, object::Rows, Modify}, Table};
-/// #
+/// # use tabled::{Table, settings::{style::{Style, BorderColor}, object::Rows, Color}};
 /// # let data: Vec<&'static str> = Vec::new();
-/// #
 /// let table = Table::new(&data)
 ///     .with(Style::ascii())
-///     .with(Modify::new(Rows::single(0)).with(BorderColor::default().top(Color::FG_RED)));
+///     .modify(Rows::single(0), BorderColor::new().set_top(Color::FG_RED));
 /// ```
-#[derive(Debug, Clone, Default, Eq, PartialEq)]
-pub struct BorderColor(Border<AnsiColor<'static>>);
+#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct BorderColor<T, B, L, R> {
+    inner: GridBorder<Color>,
+    _top: PhantomData<T>,
+    _bottom: PhantomData<B>,
+    _left: PhantomData<L>,
+    _right: PhantomData<R>,
+}
+
+impl<T, B, L, R> BorderColor<T, B, L, R> {
+    pub(crate) const fn from_border(inner: GridBorder<Color>) -> BorderColor<T, B, L, R> {
+        BorderColor {
+            inner,
+            _top: PhantomData,
+            _bottom: PhantomData,
+            _left: PhantomData,
+            _right: PhantomData,
+        }
+    }
+}
+
+impl BorderColor<(), (), (), ()> {
+    /// Creates an empty border.
+    pub const fn new() -> Self {
+        Self::from_border(GridBorder::empty())
+    }
+}
 
-impl BorderColor {
+impl BorderColor<On, On, On, On> {
     /// This function constructs a cell borders with all sides set.
     #[allow(clippy::too_many_arguments)]
-    pub fn full(
+    pub const fn full(
         top: Color,
         bottom: Color,
         left: Color,
@@ -36,93 +76,160 @@ impl BorderColor {
         bottom_left: Color,
         bottom_right: Color,
     ) -> Self {
-        Self(Border::full(
-            top.into(),
-            bottom.into(),
-            left.into(),
-            right.into(),
-            top_left.into(),
-            top_right.into(),
-            bottom_left.into(),
-            bottom_right.into(),
+        Self::from_border(GridBorder::full(
+            top,
+            bottom,
+            left,
+            right,
+            top_left,
+            top_right,
+            bottom_left,
+            bottom_right,
         ))
     }
 
-    /// This function constructs a cell borders with all sides's char set to a given character.
-    /// It behaves like [`Border::full`] with the same character set to each side.
+    /// This function constructs a cell borders with all sides's char set to a given color.
+    /// It behaves like [`Border::full`] with the same color set to each side.
     pub fn filled(c: Color) -> Self {
-        let c: AnsiColor<'_> = c.into();
-
-        Self(Border {
-            top: Some(c.clone()),
-            bottom: Some(c.clone()),
-            left: Some(c.clone()),
-            right: Some(c.clone()),
-            left_bottom_corner: Some(c.clone()),
-            left_top_corner: Some(c.clone()),
-            right_bottom_corner: Some(c.clone()),
-            right_top_corner: Some(c),
-        })
-    }
-
-    /// Set a top border character.
-    pub fn top(mut self, c: Color) -> Self {
-        self.0.top = Some(c.into());
-        self
+        Self::full(
+            c.clone(),
+            c.clone(),
+            c.clone(),
+            c.clone(),
+            c.clone(),
+            c.clone(),
+            c.clone(),
+            c,
+        )
     }
+}
 
-    /// Set a bottom border character.
-    pub fn bottom(mut self, c: Color) -> Self {
-        self.0.bottom = Some(c.into());
-        self
+impl<T, B, L, R> BorderColor<T, B, L, R> {
+    /// Set a top border color.
+    pub fn set_top(mut self, c: Color) -> BorderColor<On, B, L, R> {
+        self.inner.top = Some(c);
+        BorderColor::from_border(self.inner)
     }
 
-    /// Set a left border character.
-    pub fn left(mut self, c: Color) -> Self {
-        self.0.left = Some(c.into());
-        self
+    /// Set a bottom border color.
+    pub fn set_bottom(mut self, c: Color) -> BorderColor<T, On, L, R> {
+        self.inner.bottom = Some(c);
+        BorderColor::from_border(self.inner)
     }
 
-    /// Set a right border character.
-    pub fn right(mut self, c: Color) -> Self {
-        self.0.right = Some(c.into());
-        self
+    /// Set a left border color.
+    pub fn set_left(mut self, c: Color) -> BorderColor<T, B, On, R> {
+        self.inner.left = Some(c);
+        BorderColor::from_border(self.inner)
+    }
+
+    /// Set a right border color.
+    pub fn set_right(mut self, c: Color) -> BorderColor<T, B, L, On> {
+        self.inner.right = Some(c);
+        BorderColor::from_border(self.inner)
+    }
+
+    /// Converts a border into a general data structure.
+    pub fn into_inner(self) -> GridBorder<Color> {
+        self.inner
+    }
+}
+
+impl<T, B, L> BorderColor<T, B, L, On> {
+    /// Get a right color.
+    pub fn get_right(&self) -> Color {
+        get_color(self.inner.right.clone())
     }
+}
+
+impl<T, B, R> BorderColor<T, B, On, R> {
+    /// Get a left color.
+    pub fn get_left(&self) -> Color {
+        get_color(self.inner.left.clone())
+    }
+}
+
+impl<B, L, R> BorderColor<On, B, L, R> {
+    /// Get a top color.
+    pub fn get_top(&self) -> Color {
+        get_color(self.inner.top.clone())
+    }
+}
+
+impl<T, L, R> BorderColor<T, On, L, R> {
+    /// Get a bottom color.
+    pub fn get_bottom(&self) -> Color {
+        get_color(self.inner.bottom.clone())
+    }
+}
 
-    /// Set a top left intersection character.
-    pub fn corner_top_left(mut self, c: Color) -> Self {
-        self.0.left_top_corner = Some(c.into());
+impl<B, R> BorderColor<On, B, On, R> {
+    /// Set a top left intersection color.
+    pub fn set_corner_top_left(mut self, c: Color) -> Self {
+        self.inner.left_top_corner = Some(c);
         self
     }
 
-    /// Set a top right intersection character.
-    pub fn corner_top_right(mut self, c: Color) -> Self {
-        self.0.right_top_corner = Some(c.into());
+    /// Get a top left intersection color.
+    pub fn get_corner_top_left(&self) -> Color {
+        get_color(self.inner.left_top_corner.clone())
+    }
+}
+
+impl<B, L> BorderColor<On, B, L, On> {
+    /// Set a top right intersection color.
+    pub fn set_corner_top_right(mut self, c: Color) -> Self {
+        self.inner.right_top_corner = Some(c);
         self
     }
 
-    /// Set a bottom left intersection character.
-    pub fn corner_bottom_left(mut self, c: Color) -> Self {
-        self.0.left_bottom_corner = Some(c.into());
+    /// Get a top right intersection color.
+    pub fn get_corner_top_right(&self) -> Color {
+        get_color(self.inner.right_top_corner.clone())
+    }
+}
+
+impl<T, R> BorderColor<T, On, On, R> {
+    /// Set a bottom left intersection color.
+    pub fn set_corner_bottom_left(mut self, c: Color) -> Self {
+        self.inner.left_bottom_corner = Some(c);
         self
     }
 
-    /// Set a bottom right intersection character.
-    pub fn corner_bottom_right(mut self, c: Color) -> Self {
-        self.0.right_bottom_corner = Some(c.into());
+    /// Get a bottom left intersection color.
+    pub fn get_corner_bottom_left(&self) -> Color {
+        get_color(self.inner.left_bottom_corner.clone())
+    }
+}
+
+impl<T, L> BorderColor<T, On, L, On> {
+    /// Set a bottom right intersection color.
+    pub fn set_corner_bottom_right(mut self, c: Color) -> Self {
+        self.inner.right_bottom_corner = Some(c);
         self
     }
+
+    /// Get a bottom left intersection color.
+    pub fn get_corner_bottom_right(&self) -> Color {
+        get_color(self.inner.right_bottom_corner.clone())
+    }
+}
+
+impl<T, B, L, R> From<BorderColor<T, B, L, R>> for GridBorder<Color> {
+    fn from(value: BorderColor<T, B, L, R>) -> Self {
+        value.inner
+    }
 }
 
-impl<R> CellOption<R, ColoredConfig> for BorderColor
+impl<Data, T, B, L, R> CellOption<Data, ColoredConfig> for BorderColor<T, B, L, R>
 where
-    R: Records + ExactRecords,
+    Data: Records + ExactRecords,
 {
-    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut Data, cfg: &mut ColoredConfig, entity: Entity) {
         let count_rows = records.count_rows();
         let count_columns = records.count_columns();
 
-        let border_color = &self.0;
+        let border_color = self.inner.clone().convert();
 
         for pos in entity.iter(count_rows, count_columns) {
             cfg.set_border_color(pos, border_color.clone());
@@ -130,15 +237,15 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BorderColor
+impl<Data, D, T, B, L, R> TableOption<Data, D, ColoredConfig> for BorderColor<T, B, L, R>
 where
-    R: Records + ExactRecords,
+    Data: Records + ExactRecords,
 {
-    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut Data, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_columns = records.count_columns();
 
-        let border_color = &self.0;
+        let border_color = self.inner.clone().convert();
 
         for row in 0..count_rows {
             for col in 0..count_columns {
@@ -148,8 +255,9 @@ where
     }
 }
 
-impl From<BorderColor> for Border<AnsiColor<'static>> {
-    fn from(val: BorderColor) -> Self {
-        val.0
+fn get_color(c: Option<Color>) -> Color {
+    match c {
+        Some(c) => c,
+        None => unreachable!(),
     }
 }
diff --git a/tabled/src/settings/style/border_text.rs b/tabled/src/settings/style/border_text.rs
index 236c120..544da92 100644
--- a/tabled/src/settings/style/border_text.rs
+++ b/tabled/src/settings/style/border_text.rs
@@ -13,16 +13,16 @@ use crate::{
 
 use super::Offset;
 
-/// [`BorderText`] writes a custom text on a border.
+/// [`LineText`] writes a custom text on a border.
 ///
 /// # Example
 ///
 /// ```rust
-/// use tabled::{Table, settings::style::BorderText, settings::object::Rows};
+/// use tabled::{Table, settings::style::LineText, settings::object::Rows};
 ///
 /// let mut table = Table::new(["Hello World"]);
 /// table
-///     .with(BorderText::new("+-.table").horizontal(Rows::first()));
+///     .with(LineText::new("+-.table").horizontal(Rows::first()));
 ///
 /// assert_eq!(
 ///     table.to_string(),
@@ -34,7 +34,7 @@ use super::Offset;
 /// );
 /// ```
 #[derive(Debug)]
-pub struct BorderText<L> {
+pub struct LineText<L> {
     // todo: change to T and specify to be As<str>
     text: String,
     offset: Offset,
@@ -42,13 +42,16 @@ pub struct BorderText<L> {
     line: L,
 }
 
-impl BorderText<()> {
-    /// Creates a [`BorderText`] instance.
+impl LineText<()> {
+    /// Creates a [`LineText`] instance.
     ///
     /// Lines are numbered from 0 to the `count_rows` included
     /// (`line >= 0 && line <= count_rows`).
-    pub fn new<S: Into<String>>(text: S) -> Self {
-        BorderText {
+    pub fn new<S>(text: S) -> Self
+    where
+        S: Into<String>,
+    {
+        LineText {
             text: text.into(),
             line: (),
             offset: Offset::Begin(0),
@@ -57,10 +60,10 @@ impl BorderText<()> {
     }
 }
 
-impl<Line> BorderText<Line> {
+impl<Line> LineText<Line> {
     /// Set a line on which we will set the text.
-    pub fn horizontal<L>(self, line: L) -> BorderText<L> {
-        BorderText {
+    pub fn horizontal<L>(self, line: L) -> LineText<L> {
+        LineText {
             line,
             text: self.text,
             offset: self.offset,
@@ -69,8 +72,10 @@ impl<Line> BorderText<Line> {
     }
 
     /// Set an offset from which the text will be started.
-    pub fn offset(self, offset: Offset) -> Self {
-        BorderText {
+    pub fn offset(self, offset: impl Into<Offset>) -> Self {
+        let offset = offset.into();
+
+        LineText {
             offset,
             text: self.text,
             line: self.line,
@@ -80,7 +85,7 @@ impl<Line> BorderText<Line> {
 
     /// Set a color of the text.
     pub fn color(self, color: Color) -> Self {
-        BorderText {
+        LineText {
             color: Some(color.into()),
             text: self.text,
             line: self.line,
@@ -89,7 +94,7 @@ impl<Line> BorderText<Line> {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BorderText<usize>
+impl<R, D> TableOption<R, D, ColoredConfig> for LineText<usize>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -104,7 +109,7 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BorderText<FirstRow>
+impl<R, D> TableOption<R, D, ColoredConfig> for LineText<FirstRow>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -119,7 +124,7 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BorderText<LastRow>
+impl<R, D> TableOption<R, D, ColoredConfig> for LineText<LastRow>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -218,12 +223,15 @@ fn set_horizontal_chars<D: Dimension>(
     }
 }
 
-fn get_start_pos<D: Dimension>(
+fn get_start_pos<D>(
     cfg: &SpannedConfig,
     dims: &D,
     offset: Offset,
     count_columns: usize,
-) -> Option<usize> {
+) -> Option<usize>
+where
+    D: Dimension,
+{
     let totalw = total_width(cfg, dims, count_columns);
     match offset {
         Offset::Begin(i) => {
diff --git a/tabled/src/settings/style/builder.rs b/tabled/src/settings/style/builder.rs
index f0dbadb..6acb8bc 100644
--- a/tabled/src/settings/style/builder.rs
+++ b/tabled/src/settings/style/builder.rs
@@ -8,7 +8,10 @@ use crate::{
 };
 
 #[cfg(feature = "std")]
-use crate::grid::config::ColoredConfig;
+use crate::{
+    grid::config::{Border as GridBorder, ColoredConfig},
+    settings::Border,
+};
 
 use super::{HorizontalLine, Line, VerticalLine};
 
@@ -58,11 +61,8 @@ use super::{HorizontalLine, Line, VerticalLine};
 #[cfg_attr(not(feature = "std"), doc = "```ignore")]
 /// use tabled::{Table, settings::Style};
 ///
-/// let style = Style::ascii()
-///                 .bottom('*')
-///                 .intersection(' ');
-///
 /// let data = vec!["Hello", "2021"];
+/// let style = Style::ascii().bottom('*').intersection(' ');
 /// let table = Table::new(&data).with(style).to_string();
 ///
 /// println!("{}", table);
@@ -73,11 +73,11 @@ use super::{HorizontalLine, Line, VerticalLine};
 /// [`Style::corner_top_left`]: Style::corner_top_left
 /// [`Style::left`]: Style.left
 /// [`Style::top`]: Style.function.top
-#[derive(Debug, Clone)]
-pub struct Style<T, B, L, R, H, V, HL = HLineArray<0>, VL = VLineArray<0>> {
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Style<T, B, L, R, H, V, const HSIZE: usize = 0, const VSIZE: usize = 0> {
     borders: Borders<char>,
-    horizontals: HorizontalLineIter<HL>,
-    verticals: VerticalLineIter<VL>,
+    horizontals: HArray<L, R, V, HSIZE>,
+    verticals: VArray<T, B, H, VSIZE>,
     _top: PhantomData<T>,
     _bottom: PhantomData<B>,
     _left: PhantomData<L>,
@@ -86,15 +86,14 @@ pub struct Style<T, B, L, R, H, V, HL = HLineArray<0>, VL = VLineArray<0>> {
     _vertical: PhantomData<V>,
 }
 
-type HLineArray<const N: usize> = [HorizontalLine; N];
-
-type VLineArray<const N: usize> = [VerticalLine; N];
+type HArray<L, R, I, const N: usize> = [(usize, HorizontalLine<L, R, I>); N];
+type VArray<T, B, I, const N: usize> = [(usize, VerticalLine<T, B, I>); N];
 
 /// A marker struct which is used in [`Style`].
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Default, Hash)]
 pub struct On;
 
-impl Style<(), (), (), (), (), (), (), ()> {
+impl Style<(), (), (), (), (), ()> {
     /// This style is a style with no styling options on,
     ///
     /// ```text
@@ -196,7 +195,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
     ///      2  |   OpenSUSE   | https://www.opensuse.org/
     ///      3  | Endeavouros  | https://endeavouros.com/
     /// ```
-    pub const fn psql() -> Style<(), (), (), (), (), On, HLineArray<1>> {
+    pub const fn psql() -> Style<(), (), (), (), (), On, 1, 0> {
         Style::new(
             create_borders(
                 Line::empty(),
@@ -206,9 +205,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
                 None,
                 Some('|'),
             ),
-            [HorizontalLine::new(1, Line::empty())
-                .main(Some('-'))
-                .intersection(Some('+'))],
+            [(1, HorizontalLine::new('-').intersection('+'))],
             [],
         )
     }
@@ -222,7 +219,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
     ///     | 2  |   OpenSUSE   | https://www.opensuse.org/ |
     ///     | 3  | Endeavouros  | https://endeavouros.com/  |
     /// ```
-    pub const fn markdown() -> Style<(), (), On, On, (), On, HLineArray<1>> {
+    pub const fn markdown() -> Style<(), (), On, On, (), On, 1, 0> {
         Style::new(
             create_borders(
                 Line::empty(),
@@ -232,7 +229,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
                 Some('|'),
                 Some('|'),
             ),
-            [HorizontalLine::new(1, Line::full('-', '|', '|', '|'))],
+            [(1, HorizontalLine::full('-', '|', '|', '|'))],
             [],
         )
     }
@@ -280,7 +277,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
     ///     │ 3  │ Endeavouros  │ https://endeavouros.com/  │
     ///     └────┴──────────────┴───────────────────────────┘
     /// ```
-    pub const fn sharp() -> Style<On, On, On, On, (), On, HLineArray<1>> {
+    pub const fn sharp() -> Style<On, On, On, On, (), On, 1, 0> {
         Style::new(
             create_borders(
                 Line::full('─', '┬', '┌', '┐'),
@@ -290,12 +287,12 @@ impl Style<(), (), (), (), (), (), (), ()> {
                 Some('│'),
                 Some('│'),
             ),
-            [HorizontalLine::new(1, Line::full('─', '┼', '├', '┤'))],
+            [(1, HorizontalLine::full('─', '├', '┤', '┼'))],
             [],
         )
     }
 
-    /// This style looks like a [`Style::modern_round`] but with horizontal lines.
+    /// This style looks like a [`Style::sharp`] but with rounded corners.
     ///
     /// Beware: It uses UTF-8 characters.
     ///
@@ -304,28 +301,26 @@ impl Style<(), (), (), (), (), (), (), ()> {
     ///     │ id │ destribution │           link            │
     ///     ├────┼──────────────┼───────────────────────────┤
     ///     │ 0  │    Fedora    │  https://getfedora.org/   │
-    ///     ├────┼──────────────┼───────────────────────────┤    
     ///     │ 2  │   OpenSUSE   │ https://www.opensuse.org/ │
-    ///     ├────┼──────────────┼───────────────────────────┤
     ///     │ 3  │ Endeavouros  │ https://endeavouros.com/  │
     ///     ╰────┴──────────────┴───────────────────────────╯
     /// ```
-    pub const fn modern_round() -> Style<On, On, On, On, On, On> {
+    pub const fn rounded() -> Style<On, On, On, On, (), On, 1, 0> {
         Style::new(
             create_borders(
                 Line::full('─', '┬', '╭', '╮'),
                 Line::full('─', '┴', '╰', '╯'),
-                Line::full('─', '┼', '├', '┤'),
+                Line::empty(),
                 Some('│'),
                 Some('│'),
                 Some('│'),
             ),
-            [],
+            [(1, HorizontalLine::full('─', '├', '┤', '┼'))],
             [],
         )
     }
 
-    /// This style looks like a [`Style::sharp`] but with rounded corners.
+    /// This style looks like a [`Style::rounded`] but with horizontals lines.
     ///
     /// Beware: It uses UTF-8 characters.
     ///
@@ -334,21 +329,23 @@ impl Style<(), (), (), (), (), (), (), ()> {
     ///     │ id │ destribution │           link            │
     ///     ├────┼──────────────┼───────────────────────────┤
     ///     │ 0  │    Fedora    │  https://getfedora.org/   │
+    ///     ├────┼──────────────┼───────────────────────────┤
     ///     │ 2  │   OpenSUSE   │ https://www.opensuse.org/ │
+    ///     ├────┼──────────────┼───────────────────────────┤
     ///     │ 3  │ Endeavouros  │ https://endeavouros.com/  │
     ///     ╰────┴──────────────┴───────────────────────────╯
     /// ```
-    pub const fn rounded() -> Style<On, On, On, On, (), On, HLineArray<1>> {
+    pub const fn modern_rounded() -> Style<On, On, On, On, On, On, 0, 0> {
         Style::new(
             create_borders(
                 Line::full('─', '┬', '╭', '╮'),
                 Line::full('─', '┴', '╰', '╯'),
-                Line::empty(),
+                Line::full('─', '┼', '├', '┤'),
                 Some('│'),
                 Some('│'),
                 Some('│'),
             ),
-            [HorizontalLine::new(1, Line::full('─', '┼', '├', '┤'))],
+            [],
             [],
         )
     }
@@ -423,7 +420,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
     ///      3    Endeavouros    https://endeavouros.com/  
     ///     ==== ============== ===========================
     /// ```
-    pub const fn re_structured_text() -> Style<On, On, (), (), (), On, HLineArray<1>> {
+    pub const fn re_structured_text() -> Style<On, On, (), (), (), On, 1, 0> {
         Style::new(
             create_borders(
                 Line::new(Some('='), Some(' '), None, None),
@@ -433,10 +430,7 @@ impl Style<(), (), (), (), (), (), (), ()> {
                 None,
                 Some(' '),
             ),
-            [HorizontalLine::new(
-                1,
-                Line::new(Some('='), Some(' '), None, None),
-            )],
+            [(1, HorizontalLine::new('=').intersection(' '))],
             [],
         )
     }
@@ -468,9 +462,29 @@ impl Style<(), (), (), (), (), (), (), ()> {
     }
 }
 
-impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
-    Style<T, B, L, R, H, V, HLineArray<HN>, VLineArray<VN>>
+impl<T, B, L, R, H, V, const HSIZE: usize, const VSIZE: usize>
+    Style<T, B, L, R, H, V, HSIZE, VSIZE>
 {
+    const fn new(
+        borders: Borders<char>,
+        horizontals: HArray<L, R, V, HSIZE>,
+        verticals: VArray<T, B, H, VSIZE>,
+    ) -> Self {
+        Self {
+            borders,
+            horizontals,
+            verticals,
+            _top: PhantomData,
+            _bottom: PhantomData,
+            _left: PhantomData,
+            _right: PhantomData,
+            _horizontal: PhantomData,
+            _vertical: PhantomData,
+        }
+    }
+}
+
+impl<T, B, L, R, H, V, const HN: usize, const VN: usize> Style<T, B, L, R, H, V, HN, VN> {
     /// Set border horizontal lines.
     ///
     /// # Example
@@ -479,9 +493,15 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
     #[cfg_attr(not(feature = "derive"), doc = "```ignore")]
     /// use tabled::{settings::style::{Style, HorizontalLine, Line}, Table};
     ///
-    /// let table = Table::new((0..3).map(|i| ("Hello", i)))
-    ///    .with(Style::rounded().horizontals((1..4).map(|i| HorizontalLine::new(i, Line::filled('#')))))
-    ///    .to_string();
+    /// let data = (0..3).map(|i| ("Hello", i));
+    ///
+    /// let style = Style::rounded().horizontals([
+    ///     (1, HorizontalLine::filled('#')),
+    ///     (2, HorizontalLine::filled('&')),
+    ///     (3, HorizontalLine::filled('@')),
+    /// ]);
+    ///
+    /// let table = Table::new(data).with(style).to_string();
     ///
     /// assert_eq!(
     ///     table,
@@ -490,22 +510,19 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
     ///         "│ &str  │ i32 │\n",
     ///         "###############\n",
     ///         "│ Hello │ 0   │\n",
-    ///         "###############\n",
+    ///         "&&&&&&&&&&&&&&&\n",
     ///         "│ Hello │ 1   │\n",
-    ///         "###############\n",
+    ///         "@@@@@@@@@@@@@@@\n",
     ///         "│ Hello │ 2   │\n",
     ///         "╰───────┴─────╯",
     ///     )
     /// )
     /// ```
-    pub const fn horizontals<Lines>(
+    pub const fn horizontals<const SIZE: usize>(
         self,
-        lines: Lines,
-    ) -> Style<T, B, L, R, H, V, Lines, VLineArray<VN>>
-    where
-        Lines: IntoIterator<Item = HorizontalLine>,
-    {
-        Style::update(self.borders, HorizontalLineIter::new(lines), self.verticals)
+        list: HArray<L, R, V, SIZE>,
+    ) -> Style<T, B, L, R, H, V, SIZE, VN> {
+        Style::new(self.borders, list, self.verticals)
     }
 
     /// Set border vertical lines.
@@ -514,54 +531,56 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
     ///
     #[cfg_attr(feature = "derive", doc = "```")]
     #[cfg_attr(not(feature = "derive"), doc = "```ignore")]
-    /// use tabled::{Table, settings::style::{Style, VerticalLine, Line}};
+    /// use tabled::{settings::style::{Style, VerticalLine, Line}, Table};
     ///
-    /// let table = Table::new((0..3).map(|i| ("Hello", i)))
-    ///    .with(Style::rounded().verticals((0..3).map(|i| VerticalLine::new(i, Line::filled('#')))))
-    ///    .to_string();
+    /// let data = (0..3).map(|i| ("Hello", "World", i));
+    ///
+    /// let style = Style::rounded().verticals([
+    ///     (1, VerticalLine::new('#').top(':').bottom('.')),
+    ///     (2, VerticalLine::new('&').top(':').bottom('.')),
+    /// ]);
+    ///
+    /// let table = Table::new(data).with(style).to_string();
     ///
     /// assert_eq!(
     ///     table,
     ///     concat!(
-    ///         "#───────#─────#\n",
-    ///         "# &str  # i32 #\n",
-    ///         "├───────┼─────┤\n",
-    ///         "# Hello # 0   #\n",
-    ///         "# Hello # 1   #\n",
-    ///         "# Hello # 2   #\n",
-    ///         "#───────#─────#",
+    ///         "╭───────:───────:─────╮\n",
+    ///         "│ &str  # &str  & i32 │\n",
+    ///         "├───────┼───────┼─────┤\n",
+    ///         "│ Hello # World & 0   │\n",
+    ///         "│ Hello # World & 1   │\n",
+    ///         "│ Hello # World & 2   │\n",
+    ///         "╰───────.───────.─────╯",
     ///     )
     /// )
     /// ```
-    pub const fn verticals<Lines>(
+    pub const fn verticals<const SIZE: usize>(
         self,
-        lines: Lines,
-    ) -> Style<T, B, L, R, H, V, HLineArray<HN>, Lines>
-    where
-        Lines: IntoIterator<Item = VerticalLine>,
-    {
-        Style::update(self.borders, self.horizontals, VerticalLineIter::new(lines))
+        list: VArray<T, B, H, SIZE>,
+    ) -> Style<T, B, L, R, H, V, HN, SIZE> {
+        Style::new(self.borders, self.horizontals, list)
     }
 
     /// Removes all horizontal lines set by [`Style::horizontals`]
-    pub const fn remove_horizontals(
-        self,
-    ) -> Style<T, B, L, R, H, V, HLineArray<0>, VLineArray<VN>> {
-        Style::update(self.borders, HorizontalLineIter::new([]), self.verticals)
+    pub const fn remove_horizontals(self) -> Style<T, B, L, R, H, V, 0, VN> {
+        Style::new(self.borders, [], self.verticals)
     }
 
     /// Removes all verticals lines set by [`Style::verticals`]
-    pub const fn remove_verticals(self) -> Style<T, B, L, R, H, V, HLineArray<HN>, VLineArray<0>> {
-        Style::update(self.borders, self.horizontals, VerticalLineIter::new([]))
+    pub const fn remove_verticals(self) -> Style<T, B, L, R, H, V, HN, 0> {
+        Style::new(self.borders, self.horizontals, [])
     }
 
     /// Sets a top border.
     ///
     /// Any corners and intersections which were set will be overridden.
-    pub const fn top(
-        mut self,
-        c: char,
-    ) -> Style<On, B, L, R, H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn top(mut self, c: char) -> Style<On, B, L, R, H, V, HN, VN>
+    where
+        T: Copy,
+        B: Copy,
+        H: Copy,
+    {
         self.borders.top = Some(c);
 
         if self.borders.has_left() {
@@ -576,18 +595,24 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
             self.borders.top_intersection = Some(c);
         }
 
-        self.verticals.top = Some(CharFlag::Set(c));
+        let verticals = {
+            let lines = varray_convert(self.verticals);
+            let lines = linearr_set(lines, Line::new(None, None, Some(c), None));
+            linearr_convert_to_varray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, verticals)
     }
 
     /// Sets a bottom border.
     ///
     /// Any corners and intersections which were set will be overridden.
-    pub const fn bottom(
-        mut self,
-        c: char,
-    ) -> Style<T, On, L, R, H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn bottom(mut self, c: char) -> Style<T, On, L, R, H, V, HN, VN>
+    where
+        T: Copy,
+        B: Copy,
+        H: Copy,
+    {
         self.borders.bottom = Some(c);
 
         if self.borders.has_left() {
@@ -602,18 +627,24 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
             self.borders.bottom_intersection = Some(c);
         }
 
-        self.verticals.bottom = Some(CharFlag::Set(c));
+        let verticals = {
+            let lines = varray_convert(self.verticals);
+            let lines = linearr_set(lines, Line::new(None, None, None, Some(c)));
+            linearr_convert_to_varray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, verticals)
     }
 
     /// Sets a left border.
     ///
     /// Any corners and intersections which were set will be overridden.
-    pub const fn left(
-        mut self,
-        c: char,
-    ) -> Style<T, B, On, R, H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn left(mut self, c: char) -> Style<T, B, On, R, H, V, HN, VN>
+    where
+        L: Copy,
+        R: Copy,
+        V: Copy,
+    {
         self.borders.left = Some(c);
 
         if self.borders.has_top() {
@@ -628,18 +659,24 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
             self.borders.left_intersection = Some(c);
         }
 
-        self.horizontals.left = Some(CharFlag::Set(c));
+        let horizontals = {
+            let lines = harray_convert(self.horizontals);
+            let lines = linearr_set(lines, Line::new(None, None, Some(c), None));
+            linearr_convert_to_harray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, horizontals, self.verticals)
     }
 
     /// Sets a right border.
     ///
     /// Any corners and intersections which were set will be overridden.
-    pub const fn right(
-        mut self,
-        c: char,
-    ) -> Style<T, B, L, On, H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn right(mut self, c: char) -> Style<T, B, L, On, H, V, HN, VN>
+    where
+        L: Copy,
+        R: Copy,
+        V: Copy,
+    {
         self.borders.right = Some(c);
 
         if self.borders.has_top() {
@@ -654,18 +691,24 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
             self.borders.right_intersection = Some(c);
         }
 
-        self.horizontals.right = Some(CharFlag::Set(c));
+        let horizontals = {
+            let lines = harray_convert(self.horizontals);
+            let lines = linearr_set(lines, Line::new(None, None, None, Some(c)));
+            linearr_convert_to_harray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, horizontals, self.verticals)
     }
 
     /// Sets a horizontal split line.
     ///
     /// Any corners and intersections which were set will be overridden.
-    pub const fn horizontal(
-        mut self,
-        c: char,
-    ) -> Style<T, B, L, R, On, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn horizontal(mut self, c: char) -> Style<T, B, L, R, On, V, HN, VN>
+    where
+        T: Copy,
+        B: Copy,
+        H: Copy,
+    {
         self.borders.horizontal = Some(c);
 
         if self.borders.has_vertical() {
@@ -680,18 +723,24 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
             self.borders.right_intersection = Some(c);
         }
 
-        self.verticals.inter = Some(CharFlag::Set(c));
+        let verticals = {
+            let lines = varray_convert(self.verticals);
+            let lines = linearr_set(lines, Line::new(None, Some(c), None, None));
+            linearr_convert_to_varray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, verticals)
     }
 
     /// Sets a vertical split line.
     ///
     /// Any corners and intersections which were set will be overridden.
-    pub const fn vertical(
-        mut self,
-        c: char,
-    ) -> Style<T, B, L, R, H, On, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn vertical(mut self, c: char) -> Style<T, B, L, R, H, On, HN, VN>
+    where
+        L: Copy,
+        R: Copy,
+        V: Copy,
+    {
         self.borders.vertical = Some(c);
 
         if self.borders.has_horizontal() {
@@ -706,147 +755,275 @@ impl<T, B, L, R, H, V, const HN: usize, const VN: usize>
             self.borders.bottom_intersection = Some(c);
         }
 
-        self.horizontals.inter = Some(CharFlag::Set(c));
+        let horizontals = {
+            let lines = harray_convert(self.horizontals);
+            let lines = linearr_set(lines, Line::new(None, Some(c), None, None));
+            linearr_convert_to_harray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, horizontals, self.verticals)
     }
-}
 
-impl<T, B, L, R, H, V, HLines, VLines> Style<T, B, L, R, H, V, HLines, VLines> {
-    /// Frame function returns a frame as a border.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use tabled::{Table, settings::{Style, Highlight, object::Rows}};
-    ///
-    /// let data = [["10:52:19", "Hello"], ["10:52:20", "World"]];
-    /// let table = Table::new(data)
-    ///     .with(Highlight::new(Rows::first(), Style::modern().get_frame()))
-    ///     .to_string();
+    /// Set a vertical line.
+    /// An equvalent of calling vertical+top_intersection+bottom_intersection+intersion.
     ///
-    /// assert_eq!(
-    ///     table,
-    ///     concat!(
-    ///         "┌──────────────────┐\n",
-    ///         "│ 0        | 1     │\n",
-    ///         "└──────────────────┘\n",
-    ///         "| 10:52:19 | Hello |\n",
-    ///         "+----------+-------+\n",
-    ///         "| 10:52:20 | World |\n",
-    ///         "+----------+-------+",
-    ///     )
-    /// );
-    /// ```
-    #[cfg(feature = "std")]
-    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
-    pub const fn get_frame(&self) -> super::Border {
-        let mut border = super::Border::filled(' ');
-
-        if let Some(c) = self.borders.top {
-            border = border.top(c);
+    /// Notice, that it will clear everything that is outdated, meaning
+    /// If your style has a top border line and but the given vertical line has not got it then it will be removed.
+    pub const fn vertical_line<Top, Bottom, Intersection>(
+        mut self,
+        line: VerticalLine<Top, Bottom, Intersection>,
+    ) -> Style<Top, Bottom, L, R, Intersection, On, HN, VN>
+    where
+        L: Copy,
+        R: Copy,
+        Top: Copy,
+        Bottom: Copy,
+        Intersection: Copy,
+    {
+        let line = line.into_inner();
+
+        self.borders.vertical = line.main;
+        self.borders.intersection = line.intersection;
+        self.borders.top_intersection = line.connector1;
+        self.borders.bottom_intersection = line.connector2;
+
+        if line.intersection.is_none() {
+            self.borders.horizontal = None;
+            self.borders.left_intersection = None;
+            self.borders.right_intersection = None;
+            self.borders.intersection = None;
+        } else {
+            if self.borders.has_left() && self.borders.left_intersection.is_none() {
+                self.borders.left_intersection = Some(' ');
+            }
+
+            if self.borders.has_right() && self.borders.right_intersection.is_none() {
+                self.borders.right_intersection = Some(' ');
+            }
+
+            if self.borders.horizontal.is_none() {
+                self.borders.horizontal = Some(' ');
+            }
         }
 
-        if let Some(c) = self.borders.bottom {
-            border = border.bottom(c);
+        if line.connector1.is_none() {
+            self.borders.top = None;
+            self.borders.top_left = None;
+            self.borders.top_right = None;
+            self.borders.top_intersection = None;
+        } else if self.borders.has_top() && self.borders.top_intersection.is_none() {
+            self.borders.top_intersection = Some(' ');
         }
 
-        if let Some(c) = self.borders.left {
-            border = border.left(c);
+        if line.connector2.is_none() {
+            self.borders.bottom = None;
+            self.borders.bottom_left = None;
+            self.borders.bottom_right = None;
+            self.borders.bottom_intersection = None;
+        } else if self.borders.has_bottom() && self.borders.bottom_intersection.is_none() {
+            self.borders.bottom_intersection = Some(' ');
         }
 
-        if let Some(c) = self.borders.right {
-            border = border.right(c);
-        }
+        let horizontals = harray_convert(self.horizontals);
+        let horizontals = linearr_set(horizontals, Line::new(None, line.intersection, None, None));
+        let horizontals = linearr_convert_to_harray(horizontals);
 
-        if let Some(c) = self.borders.top_left {
-            border = border.corner_top_left(c);
-        }
+        let verticals = varray_convert(self.verticals);
+        let verticals = linearr_set(
+            verticals,
+            Line::new(None, line.intersection, line.connector1, line.connector2),
+        );
+        let verticals = linearr_convert_to_varray(verticals);
 
-        if let Some(c) = self.borders.bottom_left {
-            border = border.corner_bottom_left(c);
+        Style::new(self.borders, horizontals, verticals)
+    }
+
+    /// Set a horizontal line.
+    /// An equvalent of calling horizontal+left_intersection+right_intersection+intersion.
+    ///
+    /// Notice, that it will clear everything that is outdated, meaning
+    /// If your style has a left border line and but the given vertical line has not got it then it will be removed.
+    pub const fn horizontal_line<Left, Right, Intersection>(
+        mut self,
+        line: HorizontalLine<Left, Right, Intersection>,
+    ) -> Style<Left, Right, L, R, Intersection, On, HN, VN>
+    where
+        L: Copy,
+        R: Copy,
+        Left: Copy,
+        Right: Copy,
+        Intersection: Copy,
+    {
+        let line = line.into_inner();
+
+        self.borders.horizontal = line.main;
+        self.borders.intersection = line.intersection;
+        self.borders.left_intersection = line.connector1;
+        self.borders.right_intersection = line.connector2;
+
+        if line.intersection.is_none() {
+            self.borders.vertical = None;
+            self.borders.top_intersection = None;
+            self.borders.bottom_intersection = None;
+            self.borders.intersection = None;
+        } else {
+            if self.borders.has_top() && self.borders.top_intersection.is_none() {
+                self.borders.top_intersection = Some(' ');
+            }
+
+            if self.borders.has_bottom() && self.borders.bottom_intersection.is_none() {
+                self.borders.bottom_intersection = Some(' ');
+            }
+
+            if self.borders.vertical.is_none() {
+                self.borders.vertical = Some(' ');
+            }
         }
 
-        if let Some(c) = self.borders.top_right {
-            border = border.corner_top_right(c);
+        if line.connector1.is_none() {
+            self.borders.left = None;
+            self.borders.top_left = None;
+            self.borders.bottom_left = None;
+            self.borders.left_intersection = None;
+        } else if self.borders.has_left() && self.borders.left_intersection.is_none() {
+            self.borders.left_intersection = Some(' ');
         }
 
-        if let Some(c) = self.borders.bottom_right {
-            border = border.corner_bottom_right(c);
+        if line.connector2.is_none() {
+            self.borders.right = None;
+            self.borders.top_right = None;
+            self.borders.bottom_right = None;
+            self.borders.right_intersection = None;
+        } else if self.borders.has_right() && self.borders.right_intersection.is_none() {
+            self.borders.right_intersection = Some(' ');
         }
 
-        border
+        let horizontals = harray_convert(self.horizontals);
+        let horizontals = linearr_set(
+            horizontals,
+            Line::new(None, line.intersection, line.connector1, line.connector2),
+        );
+        let horizontals = linearr_convert_to_harray(horizontals);
+
+        let verticals = varray_convert(self.verticals);
+        let verticals = linearr_set(verticals, Line::new(None, line.intersection, None, None));
+        let verticals = linearr_convert_to_varray(verticals);
+
+        Style::new(self.borders, horizontals, verticals)
     }
 
-    /// Get a [`Style`]'s default horizontal line.
+    /// Set a frame for a style.
     ///
-    /// It doesn't return an overloaded line via [`Style::horizontals`].
+    /// It makes assumptions that a full frame will be set, but it may not be.
     ///
     /// # Example
     ///
-    #[cfg_attr(feature = "std", doc = "```")]
-    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
-    /// use tabled::{settings::style::{Style, HorizontalLine, Line}, Table};
+    /// ```
+    /// use tabled::{Table, settings::Style};
     ///
-    /// let table = Table::new((0..3).map(|i| ("Hello", "World", i)))
-    ///    .with(Style::ascii().remove_horizontal().horizontals([HorizontalLine::new(1, Style::modern().get_horizontal())]))
-    ///    .to_string();
+    /// let data = [["10:52:19", "Hello"], ["10:52:20", "World"]];
+    /// let table = Table::new(data)
+    ///     .with(Style::ascii().frame(Style::modern().get_frame()))
+    ///     .to_string();
     ///
     /// assert_eq!(
     ///     table,
     ///     concat!(
-    ///         "+-------+-------+-----+\n",
-    ///         "| &str  | &str  | i32 |\n",
-    ///         "├───────┼───────┼─────┤\n",
-    ///         "| Hello | World | 0   |\n",
-    ///         "| Hello | World | 1   |\n",
-    ///         "| Hello | World | 2   |\n",
-    ///         "+-------+-------+-----+",
+    ///         "┌──────────+───────┐\n",
+    ///         "│ 0        | 1     │\n",
+    ///         "+----------+-------+\n",
+    ///         "│ 10:52:19 | Hello │\n",
+    ///         "+----------+-------+\n",
+    ///         "│ 10:52:20 | World │\n",
+    ///         "└──────────+───────┘",
     ///     )
-    /// )
+    /// );
     /// ```
-    pub const fn get_horizontal(&self) -> Line {
-        Line::new(
-            self.borders.horizontal,
-            self.borders.intersection,
-            self.borders.left_intersection,
-            self.borders.right_intersection,
-        )
+    #[cfg(feature = "std")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+    pub const fn frame<Top, Bottom, Left, Right>(
+        mut self,
+        border: Border<Top, Bottom, Left, Right>,
+    ) -> Style<Top, Bottom, Left, Right, H, V, HN, VN>
+    where
+        T: Copy,
+        B: Copy,
+        L: Copy,
+        R: Copy,
+        H: Copy,
+        V: Copy,
+        Left: Copy,
+        Right: Copy,
+        Top: Copy,
+        Bottom: Copy,
+    {
+        let border = border.into_inner();
+        let border = correct_border(border);
+
+        let horizontals = harray_convert(self.horizontals);
+        let horizontals = linearr_set(
+            horizontals,
+            Line::new(None, None, border.left, border.right),
+        );
+        let horizontals = linearr_convert_to_harray(horizontals);
+
+        let verticals = varray_convert(self.verticals);
+        let verticals = linearr_set(verticals, Line::new(None, None, border.top, border.bottom));
+        let verticals = linearr_convert_to_varray(verticals);
+
+        self.borders.top = border.top;
+        self.borders.bottom = border.bottom;
+        self.borders.left = border.left;
+        self.borders.top_left = border.left_top_corner;
+        self.borders.bottom_left = border.left_bottom_corner;
+        self.borders.right = border.right;
+        self.borders.top_right = border.right_top_corner;
+        self.borders.bottom_right = border.right_bottom_corner;
+
+        Style::new(self.borders, horizontals, verticals)
     }
+}
 
-    /// Get a [`Style`]'s default horizontal line.
-    ///
-    /// It doesn't return an overloaded line via [`Style::verticals`].
+impl<T, B, L, R, H, V, const HSIZE: usize, const VSIZE: usize>
+    Style<T, B, L, R, H, V, HSIZE, VSIZE>
+{
+    /// Frame function returns a frame as a border.
     ///
     /// # Example
     ///
-    #[cfg_attr(feature = "std", doc = "```")]
-    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
-    /// use tabled::{settings::style::{Style, VerticalLine, Line}, Table};
+    /// ```
+    /// use tabled::{Table, settings::Style};
     ///
-    /// let table = Table::new((0..3).map(|i| ("Hello", "World", i)))
-    ///    .with(Style::ascii().remove_horizontal().verticals([VerticalLine::new(1, Style::modern().get_vertical())]))
-    ///    .to_string();
+    /// let data = [["10:52:19", "Hello"], ["10:52:20", "World"]];
+    /// let table = Table::new(data)
+    ///     .with(Style::re_structured_text().frame(Style::modern().get_frame()))
+    ///     .to_string();
     ///
     /// assert_eq!(
     ///     table,
     ///     concat!(
-    ///         "+-------┬-------+-----+\n",
-    ///         "| &str  │ &str  | i32 |\n",
-    ///         "| Hello │ World | 0   |\n",
-    ///         "| Hello │ World | 1   |\n",
-    ///         "| Hello │ World | 2   |\n",
-    ///         "+-------┴-------+-----+",
+    ///         "┌────────── ───────┐\n",
+    ///         "│ 0          1     │\n",
+    ///         "│========== =======│\n",
+    ///         "│ 10:52:19   Hello │\n",
+    ///         "│ 10:52:20   World │\n",
+    ///         "└────────── ───────┘",
     ///     )
-    /// )
+    /// );
     /// ```
-    pub const fn get_vertical(&self) -> Line {
-        Line::new(
-            self.borders.vertical,
-            self.borders.intersection,
-            self.borders.top_intersection,
-            self.borders.bottom_intersection,
-        )
+    #[cfg(feature = "std")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+    pub const fn get_frame(&self) -> Border<T, B, L, R> {
+        crate::settings::Border::from_border(crate::grid::config::Border {
+            top: self.borders.top,
+            bottom: self.borders.bottom,
+            left: self.borders.left,
+            left_top_corner: self.borders.top_left,
+            left_bottom_corner: self.borders.bottom_left,
+            right: self.borders.right,
+            right_top_corner: self.borders.top_right,
+            right_bottom_corner: self.borders.bottom_right,
+        })
     }
 
     /// Return borders of a table.
@@ -855,445 +1032,580 @@ impl<T, B, L, R, H, V, HLines, VLines> Style<T, B, L, R, H, V, HLines, VLines> {
     }
 
     /// Return custom horizontals which were set.
-    pub const fn get_horizontals(&self) -> &HLines {
-        &self.horizontals.iter
+    pub const fn get_horizontals(&self) -> HArray<L, R, V, HSIZE>
+    where
+        L: Copy,
+        R: Copy,
+        V: Copy,
+    {
+        self.horizontals
     }
 
     /// Return custom verticals which were set.
-    pub const fn get_verticals(&self) -> &VLines {
-        &self.verticals.iter
+    pub const fn get_verticals(&self) -> VArray<T, B, H, VSIZE>
+    where
+        T: Copy,
+        B: Copy,
+        H: Copy,
+    {
+        self.verticals
     }
 }
 
-impl<B, R, H, V, const HN: usize, const VN: usize>
-    Style<On, B, On, R, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<B, R, H, V, const HN: usize, const VN: usize> Style<On, B, On, R, H, V, HN, VN> {
     /// Sets a top left corner.
     pub const fn corner_top_left(mut self, c: char) -> Self {
         self.borders.top_left = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<B, L, H, V, const HN: usize, const VN: usize>
-    Style<On, B, L, On, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<B, L, H, V, const HN: usize, const VN: usize> Style<On, B, L, On, H, V, HN, VN> {
     /// Sets a top right corner.
     pub const fn corner_top_right(mut self, c: char) -> Self {
         self.borders.top_right = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<T, L, H, V, const HN: usize, const VN: usize>
-    Style<T, On, L, On, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, L, H, V, const HN: usize, const VN: usize> Style<T, On, L, On, H, V, HN, VN> {
     /// Sets a bottom right corner.
     pub const fn corner_bottom_right(mut self, c: char) -> Self {
         self.borders.bottom_right = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<T, R, H, V, const HN: usize, const VN: usize>
-    Style<T, On, On, R, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, R, H, V, const HN: usize, const VN: usize> Style<T, On, On, R, H, V, HN, VN> {
     /// Sets a bottom left corner.
     pub const fn corner_bottom_left(mut self, c: char) -> Self {
         self.borders.bottom_left = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<T, B, R, V, const HN: usize, const VN: usize>
-    Style<T, B, On, R, On, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, B, R, V, const HN: usize, const VN: usize> Style<T, B, On, R, On, V, HN, VN> {
     /// Sets a left intersection char.
     pub const fn intersection_left(mut self, c: char) -> Self {
         self.borders.left_intersection = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<T, B, L, V, const HN: usize, const VN: usize>
-    Style<T, B, L, On, On, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, B, L, V, const HN: usize, const VN: usize> Style<T, B, L, On, On, V, HN, VN> {
     /// Sets a right intersection char.
     pub const fn intersection_right(mut self, c: char) -> Self {
         self.borders.right_intersection = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<B, L, R, H, const HN: usize, const VN: usize>
-    Style<On, B, L, R, H, On, HLineArray<HN>, VLineArray<VN>>
-{
+impl<B, L, R, H, const HN: usize, const VN: usize> Style<On, B, L, R, H, On, HN, VN> {
     /// Sets a top intersection char.
     pub const fn intersection_top(mut self, c: char) -> Self {
         self.borders.top_intersection = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<T, L, R, H, const HN: usize, const VN: usize>
-    Style<T, On, L, R, H, On, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, L, R, H, const HN: usize, const VN: usize> Style<T, On, L, R, H, On, HN, VN> {
     /// Sets a bottom intersection char.
     pub const fn intersection_bottom(mut self, c: char) -> Self {
         self.borders.bottom_intersection = Some(c);
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, self.verticals)
     }
 }
 
-impl<T, B, L, R, const HN: usize, const VN: usize>
-    Style<T, B, L, R, On, On, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, B, L, R, const HN: usize, const VN: usize> Style<T, B, L, R, On, On, HN, VN> {
     /// Sets an inner intersection char.
     /// A char between horizontal and vertical split lines.
-    pub const fn intersection(mut self, c: char) -> Self {
+    pub const fn intersection(mut self, c: char) -> Self
+    where
+        T: Copy,
+        B: Copy,
+        R: Copy,
+        L: Copy,
+    {
         self.borders.intersection = Some(c);
 
-        self.horizontals.inter = Some(CharFlag::Set(c));
-        self.verticals.inter = Some(CharFlag::Set(c));
+        let horizontals = {
+            let lines = harray_convert(self.horizontals);
+            let lines = linearr_set(lines, Line::new(None, Some(c), None, None));
+            linearr_convert_to_harray(lines)
+        };
+
+        let verticals = {
+            let lines = varray_convert(self.verticals);
+            let lines = linearr_set(lines, Line::new(None, Some(c), None, None));
+            linearr_convert_to_varray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, horizontals, verticals)
     }
 }
 
-impl<B, L, R, H, V, const HN: usize, const VN: usize>
-    Style<On, B, L, R, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<B, L, R, H, V, const HN: usize, const VN: usize> Style<On, B, L, R, H, V, HN, VN> {
     /// Removes top border.
-    pub const fn remove_top(mut self) -> Style<(), B, L, R, H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn remove_top(mut self) -> Style<(), B, L, R, H, V, HN, VN>
+    where
+        B: Copy,
+        H: Copy,
+    {
         self.borders.top = None;
         self.borders.top_intersection = None;
         self.borders.top_left = None;
         self.borders.top_right = None;
 
-        self.verticals.top = Some(CharFlag::Unset);
+        let verticals = {
+            let lines = varray_convert(self.verticals);
+            let lines = linearr_unset(lines, Line::new(None, None, Some(' '), None));
+            linearr_convert_to_varray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, verticals)
     }
 }
 
-impl<T, L, R, H, V, const HN: usize, const VN: usize>
-    Style<T, On, L, R, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, L, R, H, V, const HN: usize, const VN: usize> Style<T, On, L, R, H, V, HN, VN> {
     /// Removes bottom border.
-    pub const fn remove_bottom(
-        mut self,
-    ) -> Style<T, (), L, R, H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn remove_bottom(mut self) -> Style<T, (), L, R, H, V, HN, VN>
+    where
+        T: Copy,
+        H: Copy,
+    {
         self.borders.bottom = None;
         self.borders.bottom_intersection = None;
         self.borders.bottom_left = None;
         self.borders.bottom_right = None;
 
-        self.verticals.bottom = Some(CharFlag::Unset);
+        let verticals = {
+            let lines = varray_convert(self.verticals);
+            let lines = linearr_unset(lines, Line::new(None, None, None, Some(' ')));
+            linearr_convert_to_varray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, verticals)
     }
 }
 
-impl<T, B, R, H, V, const HN: usize, const VN: usize>
-    Style<T, B, On, R, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, B, R, H, V, const HN: usize, const VN: usize> Style<T, B, On, R, H, V, HN, VN> {
     /// Removes left border.
-    pub const fn remove_left(mut self) -> Style<T, B, (), R, H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn remove_left(mut self) -> Style<T, B, (), R, H, V, HN, VN>
+    where
+        R: Copy,
+        V: Copy,
+    {
         self.borders.left = None;
         self.borders.left_intersection = None;
         self.borders.top_left = None;
         self.borders.bottom_left = None;
 
-        self.horizontals.left = Some(CharFlag::Unset);
+        let horizontals = {
+            let lines = harray_convert(self.horizontals);
+            let lines = linearr_unset(lines, Line::new(None, None, Some(' '), None));
+            linearr_convert_to_harray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, horizontals, self.verticals)
     }
 }
 
-impl<T, B, L, H, V, const HN: usize, const VN: usize>
-    Style<T, B, L, On, H, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, B, L, H, V, const HN: usize, const VN: usize> Style<T, B, L, On, H, V, HN, VN> {
     /// Removes right border.
-    pub const fn remove_right(
-        mut self,
-    ) -> Style<T, B, L, (), H, V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn remove_right(mut self) -> Style<T, B, L, (), H, V, HN, VN>
+    where
+        L: Copy,
+        V: Copy,
+    {
         self.borders.right = None;
         self.borders.right_intersection = None;
         self.borders.top_right = None;
         self.borders.bottom_right = None;
 
-        self.horizontals.right = Some(CharFlag::Unset);
+        let horizontals = {
+            let lines = harray_convert(self.horizontals);
+            let lines = linearr_unset(lines, Line::new(None, None, None, Some(' ')));
+            linearr_convert_to_harray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, horizontals, self.verticals)
     }
 }
 
-impl<T, B, L, R, V, const HN: usize, const VN: usize>
-    Style<T, B, L, R, On, V, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, B, L, R, V, const HN: usize, const VN: usize> Style<T, B, L, R, On, V, HN, VN> {
     /// Removes horizontal split lines.
     ///
     /// Not including custom split lines.
-    pub const fn remove_horizontal(
-        mut self,
-    ) -> Style<T, B, L, R, (), V, HLineArray<HN>, VLineArray<VN>> {
+    pub const fn remove_horizontal(mut self) -> Style<T, B, L, R, (), V, HN, VN>
+    where
+        T: Copy,
+        B: Copy,
+        V: Copy,
+    {
         self.borders.horizontal = None;
         self.borders.left_intersection = None;
         self.borders.right_intersection = None;
         self.borders.intersection = None;
 
-        self.verticals.inter = Some(CharFlag::Unset);
+        let verticals = {
+            let lines = varray_convert(self.verticals);
+            // let lines = linearr_unset(lines, Line::new(None, Some(' '), None, None));
+            linearr_convert_to_varray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, self.horizontals, verticals)
+    }
+
+    /// Get a [`Style`]'s default horizontal line.
+    ///
+    /// It doesn't return an overloaded line via [`Style::horizontals`].
+    ///
+    /// # Example
+    ///
+    #[cfg_attr(feature = "std", doc = "```")]
+    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
+    /// use tabled::{settings::style::{Style, HorizontalLine, Line}, Table};
+    ///
+    /// let data = (0..3).map(|i| ("Hello", "World", i));
+    /// let table = Table::new(data)
+    ///    .with(Style::ascii().remove_horizontal().horizontals([(1, Style::modern().get_horizontal_line())]))
+    ///    .to_string();
+    ///
+    /// assert_eq!(
+    ///     table,
+    ///     concat!(
+    ///         "+-------+-------+-----+\n",
+    ///         "| &str  | &str  | i32 |\n",
+    ///         "├───────┼───────┼─────┤\n",
+    ///         "| Hello | World | 0   |\n",
+    ///         "| Hello | World | 1   |\n",
+    ///         "| Hello | World | 2   |\n",
+    ///         "+-------+-------+-----+",
+    ///     )
+    /// )
+    /// ```
+    pub const fn get_horizontal_line(&self) -> HorizontalLine<L, R, V> {
+        HorizontalLine::update(Line::new(
+            self.borders.horizontal,
+            self.borders.intersection,
+            self.borders.left_intersection,
+            self.borders.right_intersection,
+        ))
     }
 }
 
-impl<T, B, L, R, H, const HN: usize, const VN: usize>
-    Style<T, B, L, R, H, On, HLineArray<HN>, VLineArray<VN>>
-{
+impl<T, B, L, R, H, const HN: usize, const VN: usize> Style<T, B, L, R, H, On, HN, VN> {
     /// Removes vertical split lines.
-    pub const fn remove_vertical(
-        mut self,
-    ) -> Style<T, B, L, R, H, (), HLineArray<HN>, VLineArray<VN>> {
+    pub const fn remove_vertical(mut self) -> Style<T, B, L, R, H, (), HN, VN>
+    where
+        R: Copy,
+        L: Copy,
+    {
         self.borders.vertical = None;
         self.borders.top_intersection = None;
         self.borders.bottom_intersection = None;
         self.borders.intersection = None;
 
-        self.horizontals.inter = Some(CharFlag::Unset);
+        let horizontals = {
+            let lines = harray_convert(self.horizontals);
+            // let lines = linearr_unset(lines, Line::new(None, Some(' '), None, None));
+            linearr_convert_to_harray(lines)
+        };
 
-        Style::update(self.borders, self.horizontals, self.verticals)
+        Style::new(self.borders, horizontals, self.verticals)
     }
-}
 
-impl<T, B, L, R, H, V, HLines, VLines> Style<T, B, L, R, H, V, HLines, VLines> {
-    const fn new(borders: Borders<char>, horizontals: HLines, verticals: VLines) -> Self {
-        Self {
-            borders,
-            horizontals: HorizontalLineIter::new(horizontals),
-            verticals: VerticalLineIter::new(verticals),
-            _top: PhantomData,
-            _bottom: PhantomData,
-            _left: PhantomData,
-            _right: PhantomData,
-            _horizontal: PhantomData,
-            _vertical: PhantomData,
-        }
-    }
-
-    const fn update(
-        borders: Borders<char>,
-        horizontals: HorizontalLineIter<HLines>,
-        verticals: VerticalLineIter<VLines>,
-    ) -> Style<T, B, L, R, H, V, HLines, VLines> {
-        Style {
-            borders,
-            horizontals,
-            verticals,
-            _top: PhantomData,
-            _bottom: PhantomData,
-            _left: PhantomData,
-            _right: PhantomData,
-            _horizontal: PhantomData,
-            _vertical: PhantomData,
-        }
+    /// Get a [`Style`]'s default horizontal line.
+    ///
+    /// It doesn't return an overloaded line via [`Style::verticals`].
+    ///
+    /// # Example
+    ///
+    #[cfg_attr(feature = "std", doc = "```")]
+    #[cfg_attr(not(feature = "std"), doc = "```ignore")]
+    /// use tabled::{settings::style::{Style, VerticalLine, Line}, Table};
+    ///
+    /// let table = Table::new((0..3).map(|i| ("Hello", "World", i)))
+    ///    .with(Style::ascii().remove_horizontal().verticals([(1, Style::modern().get_vertical_line().remove_intersection())]))
+    ///    .to_string();
+    ///
+    /// assert_eq!(
+    ///     table,
+    ///     concat!(
+    ///         "+-------┬-------+-----+\n",
+    ///         "| &str  │ &str  | i32 |\n",
+    ///         "| Hello │ World | 0   |\n",
+    ///         "| Hello │ World | 1   |\n",
+    ///         "| Hello │ World | 2   |\n",
+    ///         "+-------┴-------+-----+",
+    ///     )
+    /// )
+    /// ```
+    pub const fn get_vertical_line(&self) -> VerticalLine<T, B, H> {
+        VerticalLine::update(Line::new(
+            self.borders.vertical,
+            self.borders.intersection,
+            self.borders.top_intersection,
+            self.borders.bottom_intersection,
+        ))
     }
 }
 
 #[cfg(feature = "std")]
-impl<T, B, L, R, H, V, HLines, VLines, I, D> TableOption<I, D, ColoredConfig>
-    for Style<T, B, L, R, H, V, HLines, VLines>
-where
-    HLines: IntoIterator<Item = HorizontalLine>,
-    VLines: IntoIterator<Item = VerticalLine>,
+impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
+    TableOption<Data, Dims, ColoredConfig> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
 {
-    fn change(self, records: &mut I, cfg: &mut ColoredConfig, dimension: &mut D) {
+    fn change(self, _: &mut Data, cfg: &mut ColoredConfig, _: &mut Dims) {
         cfg.clear_theme();
         cfg.set_borders(self.borders);
 
-        for hl in self.horizontals.iter() {
-            hl.change(records, cfg, dimension);
+        for (i, line) in self.horizontals {
+            let line = line.into_inner().into();
+            cfg.insert_horizontal_line(i, line);
         }
 
-        for vl in self.verticals.iter() {
-            vl.change(records, cfg, dimension);
+        for (i, line) in self.verticals {
+            let line = line.into_inner().into();
+            cfg.insert_vertical_line(i, line);
         }
     }
 }
 
-impl<T, B, L, R, H, V, HLines, VLines, I, D> TableOption<I, D, CompactConfig>
-    for Style<T, B, L, R, H, V, HLines, VLines>
-where
-    HLines: IntoIterator<Item = HorizontalLine>,
+impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
+    TableOption<Data, Dims, CompactConfig> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
 {
-    fn change(self, records: &mut I, cfg: &mut CompactConfig, dimension: &mut D) {
+    fn change(self, _: &mut Data, cfg: &mut CompactConfig, _: &mut Dims) {
         *cfg = cfg.set_borders(self.borders);
 
-        let first_line = self.horizontals.iter().next();
-        if let Some(line) = first_line {
-            line.change(records, cfg, dimension);
+        if let Some((i, line)) = self.horizontals.get(0) {
+            if *i == 1 {
+                let line = line.into_inner().into();
+                *cfg = cfg.set_first_horizontal_line(line);
+            }
         }
     }
 }
 
-impl<T, B, L, R, H, V, HLines, VLines, I, D> TableOption<I, D, CompactMultilineConfig>
-    for Style<T, B, L, R, H, V, HLines, VLines>
-where
-    HLines: IntoIterator<Item = HorizontalLine>,
+impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
+    TableOption<Data, Dims, CompactMultilineConfig> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
 {
-    fn change(self, records: &mut I, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
-        self.change(records, cfg.as_mut(), dimension)
+    fn change(self, records: &mut Data, cfg: &mut CompactMultilineConfig, dims: &mut Dims) {
+        self.change(records, cfg.as_mut(), dims)
     }
 }
 
-/// An iterator which limits [`Line`] influence on iterations over lines for in [`Style`].
-#[derive(Debug, Clone)]
-pub struct HorizontalLineIter<I> {
-    iter: I,
-    inter: Option<CharFlag>,
-    left: Option<CharFlag>,
-    right: Option<CharFlag>,
+const fn create_borders(
+    top: Line,
+    bottom: Line,
+    horizontal: Line,
+    left: Option<char>,
+    right: Option<char>,
+    vertical: Option<char>,
+) -> Borders<char> {
+    Borders {
+        top: top.main,
+        bottom: bottom.main,
+        top_left: top.connector1,
+        top_right: top.connector2,
+        bottom_left: bottom.connector1,
+        bottom_right: bottom.connector2,
+        top_intersection: top.intersection,
+        bottom_intersection: bottom.intersection,
+        left_intersection: horizontal.connector1,
+        right_intersection: horizontal.connector2,
+        horizontal: horizontal.main,
+        intersection: horizontal.intersection,
+        left,
+        right,
+        vertical,
+    }
 }
 
-impl<I> HorizontalLineIter<I> {
-    const fn new(iter: I) -> Self {
-        Self {
-            iter,
-            inter: None,
-            left: None,
-            right: None,
-        }
+#[cfg(feature = "std")]
+const fn correct_border(mut border: GridBorder<char>) -> GridBorder<char> {
+    if border.has_top() && border.top.is_none() {
+        border.top = Some(' ');
     }
 
-    fn iter(self) -> HorizontalLineIter<I::IntoIter>
-    where
-        I: IntoIterator,
-    {
-        HorizontalLineIter {
-            iter: self.iter.into_iter(),
-            inter: self.inter,
-            left: self.left,
-            right: self.right,
-        }
+    if border.has_bottom() && border.bottom.is_none() {
+        border.bottom = Some(' ');
     }
-}
 
-impl<I> Iterator for HorizontalLineIter<I>
-where
-    I: Iterator<Item = HorizontalLine>,
-{
-    type Item = HorizontalLine;
+    if border.has_left() && border.left.is_none() {
+        border.left = Some(' ');
+    }
 
-    fn next(&mut self) -> Option<Self::Item> {
-        let mut line = self.iter.next()?;
+    if border.has_right() && border.right.is_none() {
+        border.right = Some(' ');
+    }
 
-        line_set_flag_char(&mut line.line.intersection, self.inter);
-        line_set_flag_char(&mut line.line.connector1, self.left);
-        line_set_flag_char(&mut line.line.connector2, self.right);
+    if border.has_top() && border.has_left() && border.left_top_corner.is_none() {
+        border.left_top_corner = Some(' ');
+    }
 
-        Some(line)
+    if border.has_top() && border.has_right() && border.right_top_corner.is_none() {
+        border.right_top_corner = Some(' ');
     }
-}
 
-/// An iterator which limits [`Line`] influence on iterations over lines for in [`Style`].
-#[derive(Debug, Clone)]
-pub struct VerticalLineIter<I> {
-    iter: I,
-    inter: Option<CharFlag>,
-    top: Option<CharFlag>,
-    bottom: Option<CharFlag>,
+    if border.has_bottom() && border.has_left() && border.left_top_corner.is_none() {
+        border.left_bottom_corner = Some(' ');
+    }
+
+    if border.has_bottom() && border.has_right() && border.right_bottom_corner.is_none() {
+        border.right_bottom_corner = Some(' ');
+    }
+
+    border
 }
 
-impl<I> VerticalLineIter<I> {
-    const fn new(iter: I) -> Self {
-        Self {
-            iter,
-            inter: None,
-            top: None,
-            bottom: None,
-        }
+const fn varray_convert<T, B, I, const N: usize>(lines: VArray<T, B, I, N>) -> [(usize, Line); N] {
+    let mut buf = [(0, Line::empty()); N];
+    let mut i = 0;
+    while i < N {
+        let (index, line) = &lines[i];
+        let index = *index;
+        let line = line.into_inner();
+
+        buf[i].0 = index;
+        buf[i].1 = line;
+
+        i += 1;
     }
 
-    #[cfg(feature = "std")]
-    fn iter(self) -> VerticalLineIter<I::IntoIter>
-    where
-        I: IntoIterator,
-    {
-        VerticalLineIter {
-            iter: self.iter.into_iter(),
-            inter: self.inter,
-            top: self.top,
-            bottom: self.bottom,
-        }
+    buf
+}
+
+const fn harray_convert<L, R, I, const N: usize>(lines: HArray<L, R, I, N>) -> [(usize, Line); N] {
+    let mut buf = [(0, Line::empty()); N];
+    let mut i = 0;
+    while i < N {
+        let (index, line) = &lines[i];
+        let index = *index;
+        let line = line.into_inner();
+
+        buf[i].0 = index;
+        buf[i].1 = line;
+
+        i += 1;
     }
+
+    buf
 }
 
-impl<I> Iterator for VerticalLineIter<I>
+const fn linearr_convert_to_varray<T, B, I, const N: usize>(
+    lines: [(usize, Line); N],
+) -> VArray<T, B, I, N>
 where
-    I: Iterator<Item = VerticalLine>,
+    T: Copy,
+    B: Copy,
+    I: Copy,
 {
-    type Item = VerticalLine;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let mut line = self.iter.next()?;
+    let mut buf = [(0, VerticalLine::empty()); N];
+    let mut i = 0;
+    while i < N {
+        let (index, line) = lines[i];
+        let line = VerticalLine::update(line);
 
-        line_set_flag_char(&mut line.line.intersection, self.inter);
-        line_set_flag_char(&mut line.line.connector1, self.top);
-        line_set_flag_char(&mut line.line.connector2, self.bottom);
+        buf[i].0 = index;
+        buf[i].1 = line;
 
-        Some(line)
+        i += 1;
     }
+
+    buf
 }
 
-#[derive(Debug, Clone, Copy)]
-enum CharFlag {
-    Set(char),
-    Unset,
+const fn linearr_convert_to_harray<L, R, I, const N: usize>(
+    lines: [(usize, Line); N],
+) -> HArray<L, R, I, N>
+where
+    L: Copy,
+    R: Copy,
+    I: Copy,
+{
+    let mut buf = [(0, HorizontalLine::empty()); N];
+    let mut i = 0;
+    while i < N {
+        let (index, line) = lines[i];
+        let line = HorizontalLine::update(line);
+
+        buf[i].0 = index;
+        buf[i].1 = line;
+
+        i += 1;
+    }
+
+    buf
 }
 
-fn line_set_flag_char(char: &mut Option<char>, flag: Option<CharFlag>) {
-    match flag {
-        Some(CharFlag::Set(c)) => {
-            *char = Some(c);
+const fn linearr_set<const N: usize>(lines: [(usize, Line); N], set: Line) -> [(usize, Line); N] {
+    let mut buf = [(0, Line::empty()); N];
+    let mut i = 0;
+    while i < N {
+        let (index, mut line) = lines[i];
+
+        if set.connector1.is_some() {
+            line.connector1 = set.connector1;
         }
-        Some(CharFlag::Unset) => {
-            *char = None;
+
+        if set.connector2.is_some() {
+            line.connector2 = set.connector2;
         }
-        None => {}
+
+        if set.intersection.is_some() {
+            line.intersection = set.intersection;
+        }
+
+        if set.main.is_some() {
+            line.main = set.main;
+        }
+
+        buf[i].0 = index;
+        buf[i].1 = line;
+
+        i += 1;
     }
+
+    buf
 }
 
-const fn create_borders(
-    top: Line,
-    bottom: Line,
-    horizontal: Line,
-    left: Option<char>,
-    right: Option<char>,
-    vertical: Option<char>,
-) -> Borders<char> {
-    Borders {
-        top: top.main,
-        bottom: bottom.main,
-        top_left: top.connector1,
-        top_right: top.connector2,
-        bottom_left: bottom.connector1,
-        bottom_right: bottom.connector2,
-        top_intersection: top.intersection,
-        bottom_intersection: bottom.intersection,
-        left_intersection: horizontal.connector1,
-        right_intersection: horizontal.connector2,
-        horizontal: horizontal.main,
-        intersection: horizontal.intersection,
-        left,
-        right,
-        vertical,
+const fn linearr_unset<const N: usize>(lines: [(usize, Line); N], set: Line) -> [(usize, Line); N] {
+    let mut buf = [(0, Line::empty()); N];
+    let mut i = 0;
+    while i < N {
+        let (index, mut line) = lines[i];
+
+        if set.connector1.is_some() {
+            line.connector1 = None;
+        }
+
+        if set.connector2.is_some() {
+            line.connector2 = None;
+        }
+
+        if set.intersection.is_some() {
+            line.intersection = None;
+        }
+
+        if set.main.is_some() {
+            line.main = None;
+        }
+
+        buf[i].0 = index;
+        buf[i].1 = line;
+
+        i += 1;
     }
+
+    buf
 }
+
+// todo: MACROS to reduce duplication of the same code for Varray and Harray
diff --git a/tabled/src/settings/style/horizontal_line.rs b/tabled/src/settings/style/horizontal_line.rs
index bbcdc3f..297eb32 100644
--- a/tabled/src/settings/style/horizontal_line.rs
+++ b/tabled/src/settings/style/horizontal_line.rs
@@ -1,69 +1,157 @@
-use crate::{
-    grid::config::{CompactConfig, CompactMultilineConfig},
-    settings::TableOption,
-};
+use core::marker::PhantomData;
 
-#[cfg(feature = "std")]
-use crate::grid::config::{ColoredConfig, HorizontalLine as GridLine};
-
-use super::Line;
+use crate::settings::style::{Line, On};
 
 /// A horizontal split line which can be used to set a border.
-#[cfg_attr(not(feature = "std"), allow(dead_code))]
-#[derive(Debug, Clone)]
-pub struct HorizontalLine {
-    pub(super) index: usize,
-    pub(super) line: Line,
+#[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct HorizontalLine<L, R, I> {
+    line: Line,
+    _left: PhantomData<L>,
+    _right: PhantomData<R>,
+    _intersection: PhantomData<I>,
+}
+
+impl HorizontalLine<(), (), ()> {
+    /// Creates a new horizontal split line.
+    pub const fn new(main: char) -> Self {
+        Self {
+            line: Line::new(Some(main), None, None, None),
+            _left: PhantomData,
+            _right: PhantomData,
+            _intersection: PhantomData,
+        }
+    }
+}
+
+impl<L, R, I> HorizontalLine<L, R, I> {
+    /// Creates a stub horizontal line.
+    pub const fn empty() -> Self {
+        Self {
+            line: Line::new(None, None, None, None),
+            _left: PhantomData,
+            _right: PhantomData,
+            _intersection: PhantomData,
+        }
+    }
 }
 
-impl HorizontalLine {
+impl HorizontalLine<On, On, On> {
+    /// Creates a new horizontal split line.
+    pub const fn full(main: char, left: char, right: char, intersection: char) -> Self {
+        Self {
+            line: Line::new(Some(main), Some(intersection), Some(left), Some(right)),
+            _left: PhantomData,
+            _right: PhantomData,
+            _intersection: PhantomData,
+        }
+    }
+
     /// Creates a new horizontal split line.
-    pub const fn new(index: usize, line: Line) -> Self {
-        Self { index, line }
+    pub const fn filled(main: char) -> Self {
+        Self::full(main, main, main, main)
+    }
+}
+
+impl<L, R, I> HorizontalLine<L, R, I> {
+    pub(crate) const fn update(line: Line) -> HorizontalLine<L, R, I> {
+        Self {
+            line,
+            _left: PhantomData,
+            _right: PhantomData,
+            _intersection: PhantomData,
+        }
     }
 
-    /// Sets a horizontal character.
-    pub const fn main(mut self, c: Option<char>) -> Self {
-        self.line.main = c;
-        self
+    /// Set a horizontal character.
+    pub const fn horizontal(mut self, c: char) -> HorizontalLine<L, R, I> {
+        self.line.main = Some(c);
+        HorizontalLine::update(self.line)
     }
 
-    /// Sets a vertical intersection character.
-    pub const fn intersection(mut self, c: Option<char>) -> Self {
-        self.line.intersection = c;
-        self
+    /// Set a vertical intersection character.
+    pub const fn intersection(mut self, c: char) -> HorizontalLine<L, R, On> {
+        self.line.intersection = Some(c);
+        HorizontalLine::update(self.line)
     }
 
-    /// Sets a left character.
-    pub const fn left(mut self, c: Option<char>) -> Self {
-        self.line.connector1 = c;
-        self
+    /// Set a left character.
+    pub const fn left(mut self, c: char) -> HorizontalLine<On, R, I> {
+        self.line.connector1 = Some(c);
+        HorizontalLine::update(self.line)
     }
 
-    /// Sets a right character.
-    pub const fn right(mut self, c: Option<char>) -> Self {
-        self.line.connector2 = c;
-        self
+    /// Set a right character.
+    pub const fn right(mut self, c: char) -> HorizontalLine<L, On, I> {
+        self.line.connector2 = Some(c);
+        HorizontalLine::update(self.line)
     }
 }
 
-#[cfg(feature = "std")]
-impl<R, D> TableOption<R, D, ColoredConfig> for HorizontalLine {
-    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        cfg.insert_horizontal_line(self.index, GridLine::from(self.line))
+impl<L, R, I> HorizontalLine<L, R, I> {
+    /// Get a horizontal character.
+    pub const fn get_horizontal(&self) -> char {
+        match self.line.main {
+            Some(c) => c,
+            None => unreachable!(),
+        }
+    }
+
+    /// Get a general structure of line.
+    pub const fn into_inner(&self) -> Line {
+        self.line
+    }
+}
+
+impl<L, R> HorizontalLine<L, R, On> {
+    /// Set a vertical intersection character.
+    pub const fn get_intersection(&self) -> char {
+        match self.line.intersection {
+            Some(c) => c,
+            None => unreachable!(),
+        }
+    }
+
+    /// Remove a vertical intersection character.
+    pub const fn remove_intersection(mut self) -> HorizontalLine<L, R, ()> {
+        self.line.intersection = None;
+        HorizontalLine::update(self.line)
     }
 }
 
-impl<R, D> TableOption<R, D, CompactConfig> for HorizontalLine {
-    fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
-        if self.index == 1 {
-            *cfg = cfg.set_first_horizontal_line(papergrid::config::Line::from(self.line));
+impl<R, I> HorizontalLine<On, R, I> {
+    /// Get a left character.
+    pub const fn get_left(&self) -> char {
+        match self.line.connector1 {
+            Some(c) => c,
+            None => unreachable!(),
         }
     }
+
+    /// Remove a horizontal left character.
+    pub const fn remove_left(mut self) -> HorizontalLine<(), R, I> {
+        self.line.connector1 = None;
+        HorizontalLine::update(self.line)
+    }
+}
+
+impl<L, I> HorizontalLine<L, On, I> {
+    /// Get a right character.
+    pub const fn get_right(&self) -> char {
+        match self.line.connector2 {
+            Some(c) => c,
+            None => unreachable!(),
+        }
+    }
+
+    /// Remove a horizontal right character.
+    pub const fn remove_right(mut self) -> HorizontalLine<I, (), I> {
+        self.line.connector2 = None;
+        HorizontalLine::update(self.line)
+    }
 }
 
-impl<R, D> TableOption<R, D, CompactMultilineConfig> for HorizontalLine {
-    fn change(self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
-        self.change(records, cfg.as_mut(), dimension)
+impl<L, R, I> From<HorizontalLine<L, R, I>> for Line {
+    fn from(value: HorizontalLine<L, R, I>) -> Self {
+        value.line
     }
 }
diff --git a/tabled/src/settings/style/line.rs b/tabled/src/settings/style/line.rs
index 10b3895..b1eaabb 100644
--- a/tabled/src/settings/style/line.rs
+++ b/tabled/src/settings/style/line.rs
@@ -2,7 +2,7 @@
 use crate::grid::config::{HorizontalLine, VerticalLine};
 
 /// The structure represent a vertical or horizontal line.
-#[derive(Debug, Default, Clone, Copy)]
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Line {
     pub(crate) main: Option<char>,
     pub(crate) intersection: Option<char>,
@@ -67,6 +67,18 @@ impl From<Line> for HorizontalLine {
     }
 }
 
+#[cfg(feature = "std")]
+impl From<HorizontalLine> for Line {
+    fn from(l: HorizontalLine) -> Self {
+        Self {
+            main: l.main,
+            intersection: l.intersection,
+            connector1: l.left,
+            connector2: l.right,
+        }
+    }
+}
+
 #[cfg(feature = "std")]
 impl From<Line> for VerticalLine {
     fn from(l: Line) -> Self {
@@ -79,6 +91,18 @@ impl From<Line> for VerticalLine {
     }
 }
 
+#[cfg(feature = "std")]
+impl From<VerticalLine> for Line {
+    fn from(l: VerticalLine) -> Self {
+        Self {
+            main: l.main,
+            intersection: l.intersection,
+            connector1: l.top,
+            connector2: l.bottom,
+        }
+    }
+}
+
 impl From<Line> for papergrid::config::Line<char> {
     fn from(l: Line) -> Self {
         Self {
diff --git a/tabled/src/settings/style/border_char.rs b/tabled/src/settings/style/line_char.rs
similarity index 64%
rename from tabled/src/settings/style/border_char.rs
rename to tabled/src/settings/style/line_char.rs
index b1e04c5..4dcc505 100644
--- a/tabled/src/settings/style/border_char.rs
+++ b/tabled/src/settings/style/line_char.rs
@@ -6,21 +6,21 @@ use crate::{
 
 use super::Offset;
 
-/// [`BorderChar`] sets a char to a specific location on a horizontal line.
+/// [`LineChar`] sets a char to a specific location on a horizontal line.
 ///
 /// # Example
 ///
 /// ```rust
-/// use tabled::{Table, settings::{style::{Style, BorderChar, Offset}, Modify, object::{Object, Rows, Columns}}};
+/// use tabled::{Table, settings::{style::{Style, LineChar, Offset}, Modify, object::{Object, Rows, Columns}}};
 ///
 /// let mut table = Table::new(["Hello World"]);
 /// table
 ///     .with(Style::markdown())
 ///     .with(Modify::new(Rows::single(1))
-///         .with(BorderChar::horizontal(':', Offset::Begin(0)))
-///         .with(BorderChar::horizontal(':', Offset::End(0)))
+///         .with(LineChar::horizontal(':', Offset::Begin(0)))
+///         .with(LineChar::horizontal(':', Offset::End(0)))
 ///     )
-///     .with(Modify::new((1, 0).and((1, 1))).with(BorderChar::vertical('#', Offset::Begin(0))));
+///     .with(Modify::new((1, 0).and((1, 1))).with(LineChar::vertical('#', Offset::Begin(0))));
 ///
 /// assert_eq!(
 ///     table.to_string(),
@@ -32,33 +32,39 @@ use super::Offset;
 /// );
 /// ```
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct BorderChar {
+pub struct LineChar {
     c: char,
     offset: Offset,
     horizontal: bool,
 }
 
-impl BorderChar {
-    /// Creates a [`BorderChar`] which overrides horizontal line.
-    pub fn horizontal(c: char, offset: Offset) -> Self {
+impl LineChar {
+    /// Creates a [`LineChar`] which overrides horizontal line.
+    pub fn horizontal(c: char, offset: impl Into<Offset>) -> Self {
+        let offset = offset.into();
+        let horizontal = true;
+
         Self {
             c,
             offset,
-            horizontal: true,
+            horizontal,
         }
     }
 
-    /// Creates a [`BorderChar`] which overrides vertical line.
-    pub fn vertical(c: char, offset: Offset) -> Self {
+    /// Creates a [`LineChar`] which overrides vertical line.
+    pub fn vertical(c: char, offset: impl Into<Offset>) -> Self {
+        let offset = offset.into();
+        let horizontal = false;
+
         Self {
             c,
             offset,
-            horizontal: false,
+            horizontal,
         }
     }
 }
 
-impl<R> CellOption<R, ColoredConfig> for BorderChar
+impl<R> CellOption<R, ColoredConfig> for LineChar
 where
     R: Records + ExactRecords,
 {
diff --git a/tabled/src/settings/style/mod.rs b/tabled/src/settings/style/mod.rs
index b8d7f68..aa9b07e 100644
--- a/tabled/src/settings/style/mod.rs
+++ b/tabled/src/settings/style/mod.rs
@@ -26,7 +26,7 @@
 //! )
 //! ```
 //!
-//! ## [`BorderText`]
+//! ## [`LineText`]
 //!
 //! It's used to override a border with a custom text.
 //!
@@ -34,12 +34,12 @@
 //!
 #![cfg_attr(feature = "std", doc = "```")]
 #![cfg_attr(not(feature = "std"), doc = "```ignore")]
-//! use tabled::{Table, settings::style::{BorderText, Style}};
+//! use tabled::{Table, settings::style::{LineText, Style}};
 //!
 //! let data = vec!["Hello", "2022"];
 //! let table = Table::new(&data)
 //!     .with(Style::psql())
-//!     .with(BorderText::new("Santa").horizontal(1))
+//!     .with(LineText::new("Santa").horizontal(1))
 //!     .to_string();
 //!
 //! assert_eq!(
@@ -68,7 +68,7 @@
 //! let data = vec!["Hello", "2022"];
 //! let table = Table::new(&data)
 //!     .with(Style::psql())
-//!     .with(Modify::new((0, 0)).with(Style::modern().get_frame()))
+//!     .modify((0, 0), Style::modern().get_frame())
 //!     .to_string();
 //!
 //! assert_eq!(
@@ -97,12 +97,12 @@
 #[cfg(feature = "std")]
 mod border;
 #[cfg(feature = "std")]
-mod border_char;
-#[cfg(feature = "std")]
 mod border_color;
 #[cfg(feature = "std")]
 mod border_text;
 #[cfg(feature = "std")]
+mod line_char;
+#[cfg(feature = "std")]
 mod offset;
 #[cfg(feature = "std")]
 mod raw_style;
@@ -117,11 +117,11 @@ mod vertical_line;
 #[cfg(feature = "std")]
 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
 pub use self::{
-    border::Border, border_char::BorderChar, border_color::BorderColor, border_text::BorderText,
+    border::Border, border_color::BorderColor, border_text::LineText, line_char::LineChar,
     offset::Offset, raw_style::RawStyle, span_border_correction::BorderSpanCorrection,
 };
 
-pub use builder::{HorizontalLineIter, On, Style, VerticalLineIter};
+pub use builder::{On, Style};
 pub use horizontal_line::HorizontalLine;
 pub use line::Line;
 pub use vertical_line::VerticalLine;
diff --git a/tabled/src/settings/style/offset.rs b/tabled/src/settings/style/offset.rs
index 3f8a4f8..0ea6783 100644
--- a/tabled/src/settings/style/offset.rs
+++ b/tabled/src/settings/style/offset.rs
@@ -17,3 +17,39 @@ impl From<Offset> for config::Offset {
         }
     }
 }
+
+impl From<isize> for Offset {
+    fn from(value: isize) -> Self {
+        if value > 0 {
+            Offset::Begin(value as usize)
+        } else {
+            Offset::End((-value) as usize)
+        }
+    }
+}
+
+impl From<i32> for Offset {
+    fn from(value: i32) -> Self {
+        if value > 0 {
+            Offset::Begin(value as usize)
+        } else {
+            Offset::End((-value) as usize)
+        }
+    }
+}
+
+impl From<i64> for Offset {
+    fn from(value: i64) -> Self {
+        if value > 0 {
+            Offset::Begin(value as usize)
+        } else {
+            Offset::End((-value) as usize)
+        }
+    }
+}
+
+impl From<usize> for Offset {
+    fn from(value: usize) -> Self {
+        Offset::Begin(value)
+    }
+}
diff --git a/tabled/src/settings/style/raw_style.rs b/tabled/src/settings/style/raw_style.rs
index eedb48e..ce71093 100644
--- a/tabled/src/settings/style/raw_style.rs
+++ b/tabled/src/settings/style/raw_style.rs
@@ -4,16 +4,20 @@
 use std::collections::HashMap;
 
 use crate::{
-    grid::{color::AnsiColor, config, config::Borders, config::ColoredConfig, records::Records},
+    grid::{
+        color::AnsiColor,
+        config::{self, Border, Borders, ColoredConfig},
+        records::Records,
+    },
     settings::{Color, TableOption},
 };
 
-use super::{Border, HorizontalLine, Line, Style, VerticalLine};
+use super::{Line, Style};
 
 /// A raw style data, which can be produced safely from [`Style`].
 ///
 /// It can be useful in order to not have a generics and be able to use it as a variable more conveniently.
-#[derive(Default, Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub struct RawStyle {
     borders: Borders<char>,
     colors: Borders<AnsiColor<'static>>,
@@ -207,15 +211,14 @@ impl RawStyle {
     /// use std::collections::HashMap;
     /// use tabled::{Table, settings::style::{Style, Line, RawStyle}};
     ///
-    /// let mut style = RawStyle::from(Style::re_structured_text());
+    /// let data = (0..3).map(|i| ("Hello", i));
     ///
+    /// let mut style = RawStyle::from(Style::re_structured_text());
     /// let mut lines = HashMap::new();
-    /// lines.insert(1, Style::extended().get_horizontal());
+    /// lines.insert(1, Style::extended().get_horizontal_line().into_inner());
     /// style.set_horizontals(lines);
     ///
-    /// let table = Table::new((0..3).map(|i| ("Hello", i)))
-    ///    .with(style)
-    ///    .to_string();
+    /// let table = Table::new(data).with(style).to_string();
     ///
     /// assert_eq!(
     ///     table,
@@ -254,15 +257,14 @@ impl RawStyle {
     /// use std::collections::HashMap;
     /// use tabled::{Table, settings::style::{Style, Line, RawStyle}};
     ///
-    /// let mut style = RawStyle::from(Style::re_structured_text());
+    /// let data = (0..3).map(|i| ("Hello", i));
     ///
+    /// let mut style = RawStyle::from(Style::re_structured_text());
     /// let mut lines = HashMap::new();
-    /// lines.insert(1, Style::extended().get_horizontal());
+    /// lines.insert(1, Style::extended().get_horizontal_line().into_inner());
     /// style.set_verticals(lines);
     ///
-    /// let table = Table::new((0..3).map(|i| ("Hello", i)))
-    ///    .with(style)
-    ///    .to_string();
+    /// let table = Table::new(data).with(style).to_string();
     ///
     /// assert_eq!(
     ///     table,
@@ -349,8 +351,8 @@ impl RawStyle {
     }
 
     /// Returns an outer border of the style.
-    pub fn get_frame(&self) -> Border {
-        Border::from(crate::grid::config::Border {
+    pub fn get_frame(&self) -> Border<char> {
+        Border {
             top: self.borders.top,
             bottom: self.borders.bottom,
             left: self.borders.left,
@@ -359,7 +361,7 @@ impl RawStyle {
             right_top_corner: self.borders.top_right,
             left_bottom_corner: self.borders.bottom_left,
             right_bottom_corner: self.borders.bottom_right,
-        })
+        }
     }
 
     /// Returns an general borders configuration of the style.
@@ -383,15 +385,8 @@ impl<R, D> TableOption<R, D, ColoredConfig> for RawStyle
 where
     R: Records,
 {
-    fn change(self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
-        (&self).change(records, cfg, dimension)
-    }
-}
-
-impl<R, D> TableOption<R, D, ColoredConfig> for &RawStyle {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         cfg.clear_theme();
-
         cfg.set_borders(self.borders);
 
         for (&row, line) in &self.horizontals {
@@ -408,24 +403,29 @@ impl<R, D> TableOption<R, D, ColoredConfig> for &RawStyle {
     }
 }
 
-impl<T, B, L, R, H, V, HLines, VLines> From<Style<T, B, L, R, H, V, HLines, VLines>> for RawStyle
+impl<T, B, L, R, H, V, const HSIZE: usize, const VSIZE: usize>
+    From<Style<T, B, L, R, H, V, HSIZE, VSIZE>> for RawStyle
 where
-    HLines: IntoIterator<Item = HorizontalLine> + Clone,
-    VLines: IntoIterator<Item = VerticalLine> + Clone,
+    T: Copy,
+    B: Copy,
+    L: Copy,
+    R: Copy,
+    H: Copy,
+    V: Copy,
 {
-    fn from(style: Style<T, B, L, R, H, V, HLines, VLines>) -> Self {
+    fn from(style: Style<T, B, L, R, H, V, HSIZE, VSIZE>) -> Self {
         let horizontals = style
             .get_horizontals()
-            .clone()
-            .into_iter()
-            .map(|hr| (hr.index, hr.line))
+            .map(|(i, hr)| (i, hr.into_inner()))
+            .iter()
+            .cloned()
             .collect();
 
         let verticals = style
             .get_verticals()
-            .clone()
-            .into_iter()
-            .map(|hr| (hr.index, hr.line))
+            .map(|(i, hr)| (i, hr.into_inner()))
+            .iter()
+            .cloned()
             .collect();
 
         Self {
@@ -436,3 +436,28 @@ where
         }
     }
 }
+
+impl From<ColoredConfig> for RawStyle {
+    fn from(cfg: ColoredConfig) -> Self {
+        let horizontals = cfg
+            .get_horizontal_lines()
+            .into_iter()
+            .map(|(i, line)| (i, line.into()))
+            .collect();
+        let verticals = cfg
+            .get_vertical_lines()
+            .into_iter()
+            .map(|(i, line)| (i, line.into()))
+            .collect();
+
+        let borders = *cfg.get_borders();
+        let colors = cfg.get_color_borders().clone();
+
+        Self {
+            borders,
+            horizontals,
+            verticals,
+            colors,
+        }
+    }
+}
diff --git a/tabled/src/settings/style/vertical_line.rs b/tabled/src/settings/style/vertical_line.rs
index adbef2c..0bc158f 100644
--- a/tabled/src/settings/style/vertical_line.rs
+++ b/tabled/src/settings/style/vertical_line.rs
@@ -1,50 +1,157 @@
-#[cfg(feature = "std")]
-use crate::grid::config::{ColoredConfig, VerticalLine as VLine};
+use core::marker::PhantomData;
 
-use super::Line;
+use crate::settings::style::{Line, On};
 
-/// A horizontal split line which can be used to set a border.
-#[cfg_attr(not(feature = "std"), allow(dead_code))]
-#[derive(Debug, Clone)]
-pub struct VerticalLine {
-    pub(crate) index: usize,
-    pub(crate) line: Line,
+/// A vertical split line which can be used to set a border.
+#[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct VerticalLine<T, B, I> {
+    line: Line,
+    _top: PhantomData<T>,
+    _bottom: PhantomData<B>,
+    _intersection: PhantomData<I>,
 }
 
-impl VerticalLine {
-    /// Creates a new horizontal split line.
-    pub const fn new(index: usize, line: Line) -> Self {
-        Self { index, line }
+impl VerticalLine<(), (), ()> {
+    /// Creates a new vertical split line.
+    pub const fn new(main: char) -> Self {
+        Self {
+            line: Line::new(Some(main), None, None, None),
+            _top: PhantomData,
+            _bottom: PhantomData,
+            _intersection: PhantomData,
+        }
+    }
+}
+
+impl<L, R, I> VerticalLine<L, R, I> {
+    /// Creates a stub horizontal line.
+    pub const fn empty() -> Self {
+        Self {
+            line: Line::new(None, None, None, None),
+            _top: PhantomData,
+            _bottom: PhantomData,
+            _intersection: PhantomData,
+        }
+    }
+}
+
+impl VerticalLine<On, On, On> {
+    /// Creates a new vertical split line.
+    pub const fn full(main: char, top: char, bottom: char, intersection: char) -> Self {
+        Self {
+            line: Line::new(Some(main), Some(intersection), Some(top), Some(bottom)),
+            _top: PhantomData,
+            _bottom: PhantomData,
+            _intersection: PhantomData,
+        }
+    }
+
+    /// Creates a new vertical split line.
+    pub const fn filled(main: char) -> Self {
+        Self::full(main, main, main, main)
+    }
+}
+
+impl<T, B, I> VerticalLine<T, B, I> {
+    /// Set a vertical character.
+    pub const fn vertical(mut self, c: char) -> VerticalLine<T, B, I> {
+        self.line.main = Some(c);
+        VerticalLine::update(self.line)
+    }
+
+    /// Set a vertical intersection character.
+    pub const fn intersection(mut self, c: char) -> VerticalLine<T, B, On> {
+        self.line.intersection = Some(c);
+        VerticalLine::update(self.line)
+    }
+
+    /// Set a top character.
+    pub const fn top(mut self, c: char) -> VerticalLine<On, B, I> {
+        self.line.connector1 = Some(c);
+        VerticalLine::update(self.line)
     }
 
-    /// Sets a horizontal character.
-    pub const fn main(mut self, c: Option<char>) -> Self {
-        self.line.main = c;
-        self
+    /// Set a bottom character.
+    pub const fn bottom(mut self, c: char) -> VerticalLine<T, On, I> {
+        self.line.connector2 = Some(c);
+        VerticalLine::update(self.line)
     }
+}
 
-    /// Sets a vertical intersection character.
-    pub const fn intersection(mut self, c: Option<char>) -> Self {
-        self.line.intersection = c;
-        self
+impl<T, B, I> VerticalLine<T, B, I> {
+    pub(crate) const fn update(line: Line) -> VerticalLine<T, B, I> {
+        Self {
+            line,
+            _top: PhantomData,
+            _bottom: PhantomData,
+            _intersection: PhantomData,
+        }
     }
 
-    /// Sets a top character.
-    pub const fn top(mut self, c: Option<char>) -> Self {
-        self.line.connector1 = c;
-        self
+    /// Get a vertical character.
+    pub const fn get_vertical(&self) -> char {
+        match self.line.main {
+            Some(c) => c,
+            None => unreachable!(),
+        }
+    }
+
+    /// Get a general structure of line.
+    pub const fn into_inner(&self) -> Line {
+        self.line
+    }
+}
+
+impl<T, B> VerticalLine<T, B, On> {
+    /// Set a horizontal intersection character.
+    pub const fn get_intersection(&self) -> char {
+        match self.line.intersection {
+            Some(c) => c,
+            None => unreachable!(),
+        }
+    }
+
+    /// Remove a horizontal intersection character.
+    pub const fn remove_intersection(mut self) -> VerticalLine<T, B, ()> {
+        self.line.intersection = None;
+        VerticalLine::update(self.line)
+    }
+}
+
+impl<B, I> VerticalLine<On, B, I> {
+    /// Get a top character.
+    pub const fn get_top(&self) -> char {
+        match self.line.connector1 {
+            Some(c) => c,
+            None => unreachable!(),
+        }
+    }
+
+    /// Remove a vertical top character.
+    pub const fn remove_top(mut self) -> VerticalLine<(), B, I> {
+        self.line.connector1 = None;
+        VerticalLine::update(self.line)
+    }
+}
+
+impl<T, I> VerticalLine<T, On, I> {
+    /// Get a bottom character.
+    pub const fn get_bottom(&self) -> char {
+        match self.line.connector2 {
+            Some(c) => c,
+            None => unreachable!(),
+        }
     }
 
-    /// Sets a bottom character.
-    pub const fn bottom(mut self, c: Option<char>) -> Self {
-        self.line.connector2 = c;
-        self
+    /// Remove a vertical bottom character.
+    pub const fn remove_bottom(mut self) -> VerticalLine<T, (), I> {
+        self.line.connector2 = None;
+        VerticalLine::update(self.line)
     }
 }
 
-#[cfg(feature = "std")]
-impl<R, D> crate::settings::TableOption<R, D, ColoredConfig> for VerticalLine {
-    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        cfg.insert_vertical_line(self.index, VLine::from(self.line));
+impl<T, B, I> From<VerticalLine<T, B, I>> for Line {
+    fn from(value: VerticalLine<T, B, I>) -> Self {
+        value.line
     }
 }
diff --git a/tabled/src/settings/themes/column_names.rs b/tabled/src/settings/themes/column_names.rs
index efb3680..6c3610b 100644
--- a/tabled/src/settings/themes/column_names.rs
+++ b/tabled/src/settings/themes/column_names.rs
@@ -11,7 +11,7 @@ use crate::{
         util::string::string_width,
     },
     settings::{
-        style::{BorderText, Offset},
+        style::{LineText, Offset},
         Color, TableOption,
     },
 };
@@ -293,10 +293,10 @@ fn get_border_text(
     align: AlignmentHorizontal,
     line: usize,
     color: Option<&Color>,
-) -> BorderText<usize> {
+) -> LineText<usize> {
     let left_indent = get_indent(text, align, available);
     let offset = Offset::Begin(offset + left_indent);
-    let mut btext = BorderText::new(text).horizontal(line).offset(offset);
+    let mut btext = LineText::new(text).horizontal(line).offset(offset);
     if let Some(color) = color {
         btext = btext.color(color.clone());
     }


Test patch:
diff --git a/tabled/tests/core/table_test.rs b/tabled/tests/core/table_test.rs
index 5b97063..517e2e2 100644
--- a/tabled/tests/core/table_test.rs
+++ b/tabled/tests/core/table_test.rs
@@ -259,7 +259,9 @@ test_table!(
 
 test_table!(
     table_tuple_vec,
+    #[allow(unknown_lints)]
     #[allow(clippy::needless_borrow)]
+    #[allow(clippy::needless_borrows_for_generic_args)]
     Table::new(&[(0, "Monday"), (1, "Thursday")]),
     "+-----+----------+"
     "| i32 | &str     |"
diff --git a/tabled/tests/settings/disable_test.rs b/tabled/tests/settings/disable_test.rs
index 0183e79..901998e 100644
--- a/tabled/tests/settings/disable_test.rs
+++ b/tabled/tests/settings/disable_test.rs
@@ -3,7 +3,7 @@
 use tabled::settings::{
     location::ByColumnName,
     object::{Columns, Rows, Segment},
-    style::{HorizontalLine, Style},
+    style::Style,
     Alignment, Disable, Modify,
 };
 
@@ -42,7 +42,7 @@ test_table!(
     Matrix::new(3, 3)
         .with(Modify::new(Segment::all()).with(Alignment::left()))
         .with(Disable::row(Rows::new(..1)))
-        .with(Style::modern().remove_horizontal().horizontals([HorizontalLine::new(1, Style::modern().get_horizontal())])),
+        .with(Style::modern().remove_horizontal().horizontals([(1, Style::modern().get_horizontal_line())])),
     "┌───┬─────┬─────┬─────┐"
     "│ 0 │ 0-0 │ 0-1 │ 0-2 │"
     "├───┼─────┼─────┼─────┤"
diff --git a/tabled/tests/settings/highlingt_test.rs b/tabled/tests/settings/highlingt_test.rs
index cb5ce75..90e5d76 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::new(Cell::new(1000, 0), Border::filled('+'))),
+    Matrix::new(3, 3).with(Style::modern()).with(Highlight::border(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::new(Segment::all(), Border::filled('+'))),
+        .with(Highlight::border(Segment::all(), Border::filled('+'))),
     ""
 );
 
@@ -38,8 +38,8 @@ 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::border(Cell::new(0, 0), Border::filled('+')))
+        .with(Highlight::border(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::new(Rows::single(0), Border::filled('+')))
-        .with(Highlight::new(Rows::single(3), Border::filled('*'))),
+        .with(Highlight::border(Rows::single(0), Border::filled('+')))
+        .with(Highlight::border(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::filled('+')))
-        .with(Highlight::new(Columns::single(2), Border::filled('*'))),
+        .with(Highlight::border(Columns::single(0), Border::filled('+')))
+        .with(Highlight::border(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::new(Rows::new(1..3), Border::filled('+'))),
+        .with(Highlight::border(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::new(Columns::new(..2), Border::filled('+'))),
+        .with(Highlight::border(Columns::new(..2), Border::filled('+'))),
     "++++++++++++++++──────────┬──────────┐"
     "+ N │ column 0 + column 1 │ column 2 │"
     "+───┼──────────+──────────┼──────────┤"
@@ -121,13 +121,13 @@ test_table!(
     highlingt_frame,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::new(
+        .with(Highlight::border(
             Frame,
             Border::filled('+')
-                .corner_top_left('*')
-                .corner_top_right('#')
-                .corner_bottom_left('@')
-                .corner_bottom_right('.'),
+                .set_corner_top_left('*')
+                .set_corner_top_right('#')
+                .set_corner_bottom_left('@')
+                .set_corner_bottom_right('.'),
         )),
     "*++++++++++++++++++++++++++++++++++++#"
     "+ N │ column 0 │ column 1 │ column 2 +"
@@ -144,13 +144,13 @@ test_table!(
     highlingt_full,
     Matrix::new(3, 3)
         .with(Style::modern())
-        .with(Highlight::new(
+        .with(Highlight::border(
             Segment::all(),
             Border::filled('+')
-                .corner_top_left('*')
-                .corner_top_right('#')
-                .corner_bottom_left('@')
-                .corner_bottom_right('.'),
+                .set_corner_top_left('*')
+                .set_corner_top_right('#')
+                .set_corner_bottom_left('@')
+                .set_corner_bottom_right('.'),
         )),
     "*++++++++++++++++++++++++++++++++++++#"
     "+ N │ column 0 │ column 1 │ column 2 +"
@@ -167,8 +167,8 @@ test_table!(
     highlingt_single_column,
     Matrix::table(3, 0)
         .with(Style::modern())
-        .with(Highlight::new(Cell::new(0, 0), Border::default().left('*').top('x')))
-        .with(Highlight::new(Rows::new(1..3), Border::default().left('n'))),
+        .with(Highlight::border(Cell::new(0, 0), Border::new().set_left('*').set_top('x')))
+        .with(Highlight::border(Rows::new(1..3), Border::new().set_left('n'))),
     "┌xxx┐"
     "* N │"
     "├───┤"
@@ -184,9 +184,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::border(Frame, Border::filled('*')))
+        .with(Highlight::border(Cell::new(1, 1), Border::filled('#')))
+        .with(Highlight::border(Columns::single(3), Border::filled('x'))),
     "**************************xxxxxxxxxxxx"
     "* N │ column 0 │ column 1 x column 2 x"
     "*───############──────────x──────────x"
@@ -205,7 +205,7 @@ test_table!(
 //     let data = create_vector::<3, 3>();
 //     let table = Table::new(&data)
 //         .with(Style::modern())
-//         .with(Highlight::new(Frame, Border::empty()))
+//         .with(Highlight::border(Frame, Border::empty()))
 //         .to_string();
 
 //     let expected = static_table!(
@@ -226,14 +226,14 @@ fn highlingt_complex_figures() {
     macro_rules! test_highlight {
         ($object:expr, $expected:expr,) => {
             let border = Border::filled('+')
-                .corner_top_left('*')
-                .corner_top_right('#')
-                .corner_bottom_left('@')
-                .corner_bottom_right('.');
+                .set_corner_top_left('*')
+                .set_corner_top_right('#')
+                .set_corner_bottom_left('@')
+                .set_corner_bottom_right('.');
 
             let table = Matrix::new(3, 3)
                 .with(Style::modern())
-                .with(Highlight::new($object, border))
+                .with(Highlight::border($object, border))
                 .to_string();
 
             assert_eq!(table, $expected);
diff --git a/tabled/tests/settings/margin_test.rs b/tabled/tests/settings/margin_test.rs
index 5132873..8a7c14f 100644
--- a/tabled/tests/settings/margin_test.rs
+++ b/tabled/tests/settings/margin_test.rs
@@ -12,8 +12,8 @@ test_table!(
     margin_with_table_based_on_grid_borders,
     Matrix::new(3, 3)
         .with(Style::extended())
-        .with(Highlight::new(Cell::new(0, 0), Border::filled('+')))
-        .with(Highlight::new(Cell::new(1, 1), Border::filled('*')))
+        .with(Highlight::border(Cell::new(0, 0), Border::filled('+')))
+        .with(Highlight::border(Cell::new(1, 1), Border::filled('*')))
         .with(Margin::new(1, 2, 1, 2).fill('>', '<', 'V', '^')),
     "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"
     ">+++++══════════╦══════════╦══════════╗<<"
diff --git a/tabled/tests/settings/panel_test.rs b/tabled/tests/settings/panel_test.rs
index 613fe1d..1f3c242 100644
--- a/tabled/tests/settings/panel_test.rs
+++ b/tabled/tests/settings/panel_test.rs
@@ -2,7 +2,7 @@
 
 use tabled::settings::{
     object::{Cell, Object, Rows, Segment},
-    style::{BorderSpanCorrection, HorizontalLine},
+    style::BorderSpanCorrection,
     Alignment, Border, Highlight, Modify, Panel, Span, Style, Width,
 };
 
@@ -25,7 +25,7 @@ test_table!(
     Matrix::new(3, 3)
         .with(Panel::horizontal(0,"Linux Distributions"))
         .with(Style::psql())
-        .with(Highlight::new(Cell::new(0, 0), Border::filled('#'))),
+        .with(Highlight::border(Cell::new(0, 0), Border::filled('#'))),
     "#####                                "
     "#        Linux Distributions         "
     "#####----------+----------+----------"
@@ -40,10 +40,10 @@ test_table!(
     Matrix::new(3, 3)
         .with(Panel::horizontal(0,"Linux Distributions"))
         .with(Style::psql())
-        .with(Highlight::new(Cell::new(0, 0), Border::filled('#')))
-        .with(Highlight::new(Cell::new(0, 1), Border::filled('#')))
-        .with(Highlight::new(Cell::new(0, 2), Border::filled('#')))
-        .with(Highlight::new(Cell::new(0, 3), Border::filled('#'))),
+        .with(Highlight::border(Cell::new(0, 0), Border::filled('#')))
+        .with(Highlight::border(Cell::new(0, 1), Border::filled('#')))
+        .with(Highlight::border(Cell::new(0, 2), Border::filled('#')))
+        .with(Highlight::border(Cell::new(0, 3), Border::filled('#'))),
     "######################################"
     "#        Linux Distributions         #"
     "######################################"
@@ -141,7 +141,7 @@ test_table!(
     panel_style_change,
     Matrix::iter([(0, 1)])
         .with(Panel::horizontal(0,"Numbers"))
-        .with(Style::modern().intersection_top('─').horizontals([HorizontalLine::new(1, Style::modern().get_horizontal()).intersection(Some('┬'))]))
+        .with(Style::modern().intersection_top('─').horizontals([(1, Style::modern().get_horizontal_line().intersection('┬'))]))
         .with(Modify::new(Cell::new(0, 0)).with(Alignment::center())),
     "┌───────────┐"
     "│  Numbers  │"
@@ -171,7 +171,7 @@ test_table!(
     panel_style_change_correct,
     Matrix::iter([(0, 1)])
         .with(Panel::horizontal(0,"Numbers"))
-        .with(Style::modern().intersection_top('─').horizontals([HorizontalLine::new(1, Style::modern().get_horizontal()).intersection(Some('┬'))]))
+        .with(Style::modern().intersection_top('─').horizontals([(1, Style::modern().get_horizontal_line().intersection('┬'))]))
         .with(BorderSpanCorrection)
         .with(Modify::new(Cell::new(0, 0)).with(Alignment::center())),
     "┌───────────┐"
@@ -185,7 +185,9 @@ test_table!(
 
 test_table!(
     panel_in_single_column,
+    #[allow(unknown_lints)]
     #[allow(clippy::needless_borrow)]
+    #[allow(clippy::needless_borrows_for_generic_args)]
     Matrix::iter(&[(0)]).with(Panel::horizontal(0,"Numbers")).with(Style::modern()),
     "┌─────────┐"
     "│ Numbers │"
diff --git a/tabled/tests/settings/rotate_test.rs b/tabled/tests/settings/rotate_test.rs
index 42a7818..7537888 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::default().top('*')))
+        .with(Highlight::border(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::default().bottom('*')))
+        .with(Highlight::border(Cell::new(0, 2), Border::new().set_bottom('*')))
         .with(Rotate::Left),
         "+-----+-----+-----+-----+"
         "| i32 | 789 | 891 | 333 |"
diff --git a/tabled/tests/settings/span_test.rs b/tabled/tests/settings/span_test.rs
index ed61d86..5e564f3 100644
--- a/tabled/tests/settings/span_test.rs
+++ b/tabled/tests/settings/span_test.rs
@@ -1042,7 +1042,7 @@ mod row {
         let table = Table::new(data)
             .with(Modify::new((1, 1)).with(Span::row(3)))
             .with(Style::modern())
-            .with(Highlight::new(Columns::single(1), Border::filled('*')))
+            .with(Highlight::border(Columns::single(1), Border::filled('*')))
             .to_string();
 
         assert_eq!(
@@ -1075,7 +1075,7 @@ fn highlight_row_col_span_test() {
     let table = Table::new(data)
         .with(Modify::new((1, 1)).with(Span::row(3)).with(Span::column(2)))
         .with(Style::modern())
-        .with(Highlight::new(Columns::new(1..3), Border::filled('*')))
+        .with(Highlight::border(Columns::new(1..3), Border::filled('*')))
         .to_string();
 
     assert_eq!(
diff --git a/tabled/tests/settings/style_test.rs b/tabled/tests/settings/style_test.rs
index d4d53c0..000e66f 100644
--- a/tabled/tests/settings/style_test.rs
+++ b/tabled/tests/settings/style_test.rs
@@ -1,14 +1,15 @@
 #![cfg(feature = "std")]
 
-use std::iter::FromIterator;
+use std::{collections::HashMap, iter::FromIterator};
 
 use tabled::{
     builder::Builder,
+    grid::config::Border as GridBorder,
     settings::{
         object::{Columns, Rows, Segment},
         style::{
-            Border, BorderChar, BorderColor, BorderSpanCorrection, BorderText, HorizontalLine,
-            Line, Offset, On, RawStyle, Style, VerticalLine,
+            Border, BorderColor, BorderSpanCorrection, HorizontalLine, Line, LineChar, LineText,
+            Offset, On, RawStyle, Style, VerticalLine,
         },
         Color, Format, Highlight, Modify, Padding, Span,
     },
@@ -83,7 +84,7 @@ test_table!(
 
 test_table!(
     modern_round_style,
-    Matrix::new(3, 3).with(Style::modern_round()),
+    Matrix::new(3, 3).with(Style::modern_rounded()),
     "╭───┬──────────┬──────────┬──────────╮"
     "│ N │ column 0 │ column 1 │ column 2 │"
     "├───┼──────────┼──────────┼──────────┤"
@@ -109,7 +110,7 @@ test_table!(
 
 test_table!(
     modern_clean_style,
-    Matrix::new(3, 3).with(Style::modern().remove_horizontal().horizontals(vec![HorizontalLine::new(1, Style::modern().get_horizontal())])),
+    Matrix::new(3, 3).with(Style::modern().remove_horizontal().horizontals([(1, Style::modern().get_horizontal_line())])),
     "┌───┬──────────┬──────────┬──────────┐"
     "│ N │ column 0 │ column 1 │ column 2 │"
     "├───┼──────────┼──────────┼──────────┤"
@@ -208,15 +209,15 @@ test_table!(
             .horizontal('`')
             .intersection('\'')
             .intersection_bottom('\'')
-            .horizontals(vec![HorizontalLine::new(1, Line::full('x', '*', 'q', 'w'))])),
-    "  N ' column 0 ' column 1 ' column 2  "
-    "qxxx*xxxxxxxxxx*xxxxxxxxxx*xxxxxxxxxxw"
-    "  0 '   0-0    '   0-1    '   0-2     "
-    " ```'``````````'``````````'`````````` "
-    "  1 '   1-0    '   1-1    '   1-2     "
-    " ```'``````````'``````````'`````````` "
-    "  2 '   2-0    '   2-1    '   2-2     "
-    " ***'**********'**********'********** "
+            .horizontals([(1, HorizontalLine::new('x').intersection('*'))])),
+    " N ' column 0 ' column 1 ' column 2 "
+    "xxx*xxxxxxxxxx*xxxxxxxxxx*xxxxxxxxxx"
+    " 0 '   0-0    '   0-1    '   0-2    "
+    "```'``````````'``````````'``````````"
+    " 1 '   1-0    '   1-1    '   1-2    "
+    "```'``````````'``````````'``````````"
+    " 2 '   2-0    '   2-1    '   2-2    "
+    "***'**********'**********'**********"
 );
 
 test_table!(
@@ -235,7 +236,7 @@ test_table!(
 
 test_table!(
     top_border_override_first_test,
-    Matrix::table(2, 2).with(BorderText::new("-Table").horizontal(Rows::first())),
+    Matrix::table(2, 2).with(LineText::new("-Table").horizontal(Rows::first())),
     "-Table---------+----------+"
     "| N | column 0 | column 1 |"
     "+---+----------+----------+"
@@ -247,7 +248,7 @@ test_table!(
 
 test_table!(
     top_border_override_last_test,
-    Matrix::table(2, 2).with(BorderText::new("-Table").horizontal(Rows::last())),
+    Matrix::table(2, 2).with(LineText::new("-Table").horizontal(Rows::last())),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+----------+----------+"
@@ -260,8 +261,8 @@ test_table!(
 test_table!(
     top_border_override_new_test,
     Matrix::table(2, 2)
-        .with(BorderText::new("-Table").horizontal(1))
-        .with(BorderText::new("-Table").horizontal(2)),
+        .with(LineText::new("-Table").horizontal(1))
+        .with(LineText::new("-Table").horizontal(2)),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "-Table---------+----------+"
@@ -273,7 +274,7 @@ test_table!(
 
 test_table!(
     top_border_override_new_doesnt_panic_when_index_is_invalid,
-    Matrix::table(2, 2).with(BorderText::new("-Table").horizontal(100)),
+    Matrix::table(2, 2).with(LineText::new("-Table").horizontal(100)),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+----------+----------+"
@@ -287,7 +288,7 @@ test_table!(
     top_override_doesnt_work_with_style_with_no_top_border_test,
     Matrix::table(2, 2)
         .with(Style::psql())
-        .with(BorderText::new("-Table").horizontal(Rows::first())),
+        .with(LineText::new("-Table").horizontal(Rows::first())),
     " N | column 0 | column 1 "
     "---+----------+----------"
     " 0 |   0-0    |   0-1    "
@@ -297,7 +298,7 @@ test_table!(
 test_table!(
     top_border_override_cleared_after_restyling_test,
     Matrix::table(2, 2)
-        .with(BorderText::new("-Table").horizontal(Rows::first()))
+        .with(LineText::new("-Table").horizontal(Rows::first()))
         .with(Style::ascii()),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
@@ -311,7 +312,7 @@ test_table!(
 test_table!(
     top_border_override_with_big_string_test,
     Matrix::table(2, 2)
-        .with(BorderText::new("-Tableeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1231").horizontal(Rows::first())),
+        .with(LineText::new("-Tableeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1231").horizontal(Rows::first())),
     "-Tableeeeeeeeeeeeeeeeeeeeee"
     "| N | column 0 | column 1 |"
     "+---+----------+----------+"
@@ -325,8 +326,8 @@ test_table!(
     border_text_0,
     Matrix::table(2, 2)
         .with(Style::empty())
-        .with(Modify::new(Rows::first()).with(Border::default().bottom('-')))
-        .with(BorderText::new("-Table").horizontal(1)),
+        .with(Modify::new(Rows::first()).with(Border::new().set_bottom('-')))
+        .with(LineText::new("-Table").horizontal(1)),
     " N  column 0  column 1 "
     "-Table-----------------"
     " 0    0-0       0-1    "
@@ -335,7 +336,7 @@ test_table!(
 
 test_table!(
     border_color_global,
-    { Matrix::table(2, 2).with(BorderColor::default().bottom(Color::FG_RED)) },
+    { Matrix::table(2, 2).with(BorderColor::new().set_bottom(Color::FG_RED)) },
     "+---+----------+----------+\n\
      | N | column 0 | column 1 |\n\
      +\u{1b}[31m---\u{1b}[39m+\u{1b}[31m----------\u{1b}[39m+\u{1b}[31m----------\u{1b}[39m+\n\
@@ -349,10 +350,10 @@ test_table!(
 test_table!(
     border_text_colored,
     Matrix::table(2, 2)
-        .with(BorderText::new("-Table").horizontal(1))
-        .with(BorderText::new("-Table213123").horizontal(2))
-        .with(Modify::new(Rows::single(1)).with(BorderColor::default().bottom(Color::FG_RED)))
-        .with(Modify::new(Rows::single(2)).with(BorderColor::default().bottom(Color::try_from(" ".blue().on_green().to_string()).unwrap()))),
+        .with(LineText::new("-Table").horizontal(1))
+        .with(LineText::new("-Table213123").horizontal(2))
+        .with(Modify::new(Rows::single(1)).with(BorderColor::new().set_bottom(Color::FG_RED)))
+        .with(Modify::new(Rows::single(2)).with(BorderColor::new().set_bottom(Color::try_from(" ".blue().on_green().to_string()).unwrap()))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "-Table---------+----------+"
@@ -364,7 +365,7 @@ test_table!(
 
 test_table!(
     border_text_offset_test_0,
-    Matrix::table(2, 2).with(BorderText::new("-Table").horizontal(1).offset(Offset::Begin(5))),
+    Matrix::table(2, 2).with(LineText::new("-Table").horizontal(1).offset(Offset::Begin(5))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+-Table----+----------+"
@@ -376,7 +377,7 @@ test_table!(
 
 test_table!(
     border_text_offset_test_1,
-    Matrix::table(2, 2).with(BorderText::new("-Table").horizontal(1).offset(Offset::Begin(15))),
+    Matrix::table(2, 2).with(LineText::new("-Table").horizontal(1).offset(Offset::Begin(15))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+-----------Table-----+"
@@ -388,7 +389,7 @@ test_table!(
 
 test_table!(
     border_text_offset_test_2,
-    Matrix::table(2, 2).with(BorderText::new("Table").horizontal(1).offset(Offset::End(5))),
+    Matrix::table(2, 2).with(LineText::new("Table").horizontal(1).offset(Offset::End(5))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+----------+------Table"
@@ -400,7 +401,7 @@ test_table!(
 
 test_table!(
     border_text_offset_test_3,
-    Matrix::table(2, 2).with(BorderText::new("Table").horizontal(1).offset(Offset::End(15))),
+    Matrix::table(2, 2).with(LineText::new("Table").horizontal(1).offset(Offset::End(15))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+-------Table---------+"
@@ -412,7 +413,7 @@ test_table!(
 
 test_table!(
     border_text_offset_test_4,
-    Matrix::table(2, 2).with(BorderText::new("Table").horizontal(1).offset(Offset::End(21))),
+    Matrix::table(2, 2).with(LineText::new("Table").horizontal(1).offset(Offset::End(21))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+-Table----+----------+"
@@ -424,7 +425,7 @@ test_table!(
 
 test_table!(
     border_text_offset_test_5,
-    Matrix::table(2, 2).with(BorderText::new("Table").horizontal(1).offset(Offset::End(25))),
+    Matrix::table(2, 2).with(LineText::new("Table").horizontal(1).offset(Offset::End(25))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+-Table--------+----------+"
@@ -436,7 +437,7 @@ test_table!(
 
 test_table!(
     border_text_offset_test_6,
-    Matrix::table(2, 2).with(BorderText::new("-Table").horizontal(1).offset(Offset::Begin(21))),
+    Matrix::table(2, 2).with(LineText::new("-Table").horizontal(1).offset(Offset::Begin(21))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+----------+------Table"
@@ -448,7 +449,7 @@ test_table!(
 
 test_table!(
     border_override_color,
-    Matrix::table(2, 2).with(BorderText::new("-Table").horizontal(Rows::first()).color(Color::FG_BLUE)),
+    Matrix::table(2, 2).with(LineText::new("-Table").horizontal(Rows::first()).color(Color::FG_BLUE)),
     "\u{1b}[34m-\u{1b}[39m\u{1b}[34mT\u{1b}[39m\u{1b}[34ma\u{1b}[39m\u{1b}[34mb\u{1b}[39m\u{1b}[34ml\u{1b}[39m\u{1b}[34me\u{1b}[39m---------+----------+"
     "| N | column 0 | column 1 |"
     "+---+----------+----------+"
@@ -511,7 +512,7 @@ test_table!(
 
 test_table!(
     border_test_0,
-    Matrix::table(2, 2).with(Modify::new(Rows::single(1)).with(Border::filled('*').top('#'))),
+    Matrix::table(2, 2).with(Modify::new(Rows::single(1)).with(Border::filled('*').set_top('#'))),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "*###*##########*##########*"
@@ -525,7 +526,7 @@ test_table!(
     border_test_1,
     Matrix::table(2, 2)
         .with(Style::empty())
-        .with(Modify::new(Rows::single(1)).with(Border::filled('*').top('#'))),
+        .with(Modify::new(Rows::single(1)).with(Border::filled('*').set_top('#'))),
     "  N   column 0   column 1  "
     "*###*##########*##########*"
     "* 0 *   0-0    *   0-1    *"
@@ -535,7 +536,7 @@ test_table!(
 
 test_table!(
     style_frame_test_0,
-    Matrix::table(2, 2).with(Highlight::new(Rows::single(1), Style::modern().get_frame())),
+    Matrix::table(2, 2).with(Highlight::border(Rows::single(1), Style::modern().get_frame())),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "┌─────────────────────────┐"
@@ -549,8 +550,8 @@ test_table!(
     style_frame_test_1,
     Matrix::table(2, 2)
         .with(Style::blank())
-        .with(Highlight::new(Rows::single(0), Style::extended().get_frame()))
-        .with(Highlight::new(Rows::single(2), Style::extended().get_frame())),
+        .with(Highlight::border(Rows::single(0), Style::extended().get_frame()))
+        .with(Highlight::border(Rows::single(2), Style::extended().get_frame())),
     "╔═════════════════════════╗"
     "║ N   column 0   column 1 ║"
     "╚═════════════════════════╝"
@@ -581,7 +582,7 @@ test_table!(
 
 test_table!(
     empty_border_text_doesnt_panic_test,
-    Matrix::table(2, 2).with(BorderText::new("").horizontal(0)),
+    Matrix::table(2, 2).with(LineText::new("").horizontal(0)),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
     "+---+----------+----------+"
@@ -705,7 +706,7 @@ test_table!(
             style.set_bottom(None);
             style
         })
-        .with(Modify::new(Rows::last()).with(Border::default().corner_bottom_left('*'))),
+        .with(Modify::new(Rows::last()).with(GridBorder { left_bottom_corner: Some('*'), ..Default::default() })),
     "┌───┬─────────────────┬──────────┬──────────┐"
     "│ N │    column 0     │ column 1 │ column 2 │"
     "├───┼─────────────────┼──────────┼──────────┤"
@@ -721,7 +722,7 @@ test_table!(
     border_none_test_0,
     Matrix::table(2, 2)
         .with(Style::ascii())
-        .with(Modify::new(Rows::single(1)).with(Border::filled('*').top('#')))
+        .with(Modify::new(Rows::single(1)).with(Border::filled('*').set_top('#')))
         .with(Modify::new(Rows::single(1)).with(Border::empty())),
     "+---+----------+----------+"
     "| N | column 0 | column 1 |"
@@ -736,7 +737,7 @@ test_table!(
     border_none_test_1,
     Matrix::table(2, 2)
         .with(Style::empty())
-        .with(Modify::new(Rows::single(1)).with(Border::filled('*').top('#')))
+        .with(Modify::new(Rows::single(1)).with(Border::filled('*').set_top('#')))
         .with(Modify::new(Columns::single(1)).with(Border::empty())),
     "  N  column 0  column 1  "
     "*###          ##########*"
@@ -750,6 +751,7 @@ fn custom_style_test() {
     macro_rules! test_style {
         ($style:expr, $expected:expr $(,)*) => {
             let table = Matrix::new(3, 3).with($style).to_string();
+            println!("{table}");
             assert_eq!(table, $expected);
         };
     }
@@ -807,7 +809,7 @@ fn custom_style_test() {
         ),
     );
     test_style!(
-        Style::empty().horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('-'))]),
+        Style::empty().horizontals([(1, HorizontalLine::new('-'))]),
         static_table!(
             " N  column 0  column 1  column 2 "
             "---------------------------------"
@@ -885,7 +887,7 @@ fn custom_style_test() {
     test_style!(
         Style::empty()
             .top('-')
-            .horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('+'))]),
+            .horizontals([(1, HorizontalLine::new('+'))]),
         static_table!(
             "---------------------------------"
             " N  column 0  column 1  column 2 "
@@ -953,7 +955,7 @@ fn custom_style_test() {
     test_style!(
         Style::empty()
             .bottom('-')
-            .horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('+'))]),
+            .horizontals([(1, HorizontalLine::new('+'))]),
         static_table!(
             " N  column 0  column 1  column 2 "
             "+++++++++++++++++++++++++++++++++"
@@ -1017,7 +1019,7 @@ fn custom_style_test() {
     test_style!(
         Style::empty()
             .left('-')
-            .horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('+'))]),
+            .horizontals([(1, HorizontalLine::new('+').left(' '))]),
         static_table!(
             "- N  column 0  column 1  column 2 "
             " +++++++++++++++++++++++++++++++++"
@@ -1080,7 +1082,7 @@ fn custom_style_test() {
     test_style!(
         Style::empty()
             .right('-')
-            .horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('+'))]),
+            .horizontals([(1, HorizontalLine::new('+').right(' '))]),
         static_table!(
             " N  column 0  column 1  column 2 -"
             "+++++++++++++++++++++++++++++++++ "
@@ -1143,7 +1145,7 @@ fn custom_style_test() {
     test_style!(
         Style::empty()
             .vertical('-')
-            .horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('+'))]),
+            .horizontals([(1, HorizontalLine::new('+').intersection(' '))]),
         static_table!(
             " N - column 0 - column 1 - column 2 "
             "+++ ++++++++++ ++++++++++ ++++++++++"
@@ -1218,7 +1220,7 @@ fn custom_style_test() {
     test_style!(
         Style::empty()
             .horizontal('-')
-            .horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('+'))]),
+            .horizontals([(1, HorizontalLine::new('+'))]),
         static_table!(
             " N  column 0  column 1  column 2 "
             "+++++++++++++++++++++++++++++++++"
@@ -1233,7 +1235,7 @@ fn custom_style_test() {
     test_style!(
         Style::empty()
             .top('+')
-            .horizontals(vec![HorizontalLine::new(1, Line::default()).main(Some('-'))]),
+            .horizontals([(1, HorizontalLine::new('-'))]),
         static_table!(
             "+++++++++++++++++++++++++++++++++"
             " N  column 0  column 1  column 2 "
@@ -1245,7 +1247,7 @@ fn custom_style_test() {
     );
     test_style!(
         Style::empty()
-            .horizontals([HorizontalLine::new(1, Line::default()).main(Some('-'))])
+            .horizontals([(1, HorizontalLine::new('-'))])
             .bottom('+'),
         static_table!(
             " N  column 0  column 1  column 2 "
@@ -1258,7 +1260,7 @@ fn custom_style_test() {
     );
     test_style!(
         Style::empty()
-            .horizontals([HorizontalLine::new(1, Line::default()).main(Some('-'))])
+            .horizontals([(1, HorizontalLine::new('-'))])
             .left('+'),
         static_table!(
             "+ N  column 0  column 1  column 2 "
@@ -1270,7 +1272,7 @@ fn custom_style_test() {
     );
     test_style!(
         Style::empty()
-            .horizontals([HorizontalLine::new(1, Line::default()).main(Some('-'))])
+            .horizontals([(1, HorizontalLine::new('-'))])
             .right('+'),
         static_table!(
             " N  column 0  column 1  column 2 +"
@@ -1282,7 +1284,7 @@ fn custom_style_test() {
     );
     test_style!(
         Style::empty()
-            .horizontals([HorizontalLine::new(1, Line::default()).main(Some('-'))])
+            .horizontals([(1, HorizontalLine::new('-'))])
             .vertical('+'),
         static_table!(
             " N + column 0 + column 1 + column 2 "
@@ -1294,7 +1296,7 @@ fn custom_style_test() {
     );
     test_style!(
         Style::empty()
-            .horizontals([HorizontalLine::new(1, Line::default()).main(Some('-'))])
+            .horizontals([(1, HorizontalLine::new('-'))])
             .horizontal('+'),
         static_table!(
             " N  column 0  column 1  column 2 "
@@ -1316,7 +1318,7 @@ fn custom_style_test() {
             .left('|')
             .right('*')
             .horizontal('x')
-            .horizontals([HorizontalLine::new(1, Line::filled('z'))])
+            .horizontals([(1, HorizontalLine::filled('z').remove_intersection())])
             .vertical('#'),
         static_table!(
             "|---#----------#----------#----------*"
@@ -1347,7 +1349,8 @@ fn custom_style_test() {
         .corner_bottom_left('?')
         .corner_top_right('.')
         .corner_bottom_right('%')
-        .horizontals([HorizontalLine::new(1, Line::full(',', '#', ',', ','))]);
+        .horizontals([(1, HorizontalLine::full(',', ',', ',', '#'))]);
+
     test_style!(
         full_style.clone(),
         static_table!(
@@ -1452,7 +1455,7 @@ fn custom_style_test() {
     test_style!(
         full_style
             .clone()
-            .horizontals(vec![HorizontalLine::new(1, Line::filled('q'))]),
+            .horizontals([(1, HorizontalLine::filled('q'))]),
         static_table!(
             ";---!----------!----------!----------."
             "| N # column 0 # column 1 # column 2 *"
@@ -1484,10 +1487,7 @@ fn custom_style_test() {
     );
     test_style!(Style::empty().vertical('-').remove_vertical(), empty_table);
     test_style!(
-        Style::empty().horizontals(vec![HorizontalLine::new(
-            1,
-            Line::new(Some('-'), None, None, None)
-        )]),
+        Style::empty().horizontals([(1, HorizontalLine::new('-'))]),
         static_table!(
             " N  column 0  column 1  column 2 "
             "---------------------------------"
@@ -1608,7 +1608,7 @@ fn test_default_border_usage() {
     }
 
     test_border! {
-        Modify::new((3, 2)).with(Border::default().corner_bottom_left('*')),
+        Modify::new((3, 2)).with(Border::new().set_bottom(' ').set_left(' ').set_corner_bottom_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1618,7 +1618,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().corner_bottom_right('*')),
+        Modify::new((3, 2)).with(Border::new().set_bottom(' ').set_right(' ').set_corner_bottom_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1628,7 +1628,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().bottom('*')),
+        Modify::new((3, 2)).with(Border::new().set_bottom('*')),
         static_table!(
             " N     column 0      column 1  column 2 "
             " 0  a longer string    0-1       0-2    "
@@ -1638,7 +1638,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().bottom('*').corner_bottom_left('#')),
+        Modify::new((3, 2)).with(Border::new().set_bottom('*').set_left(' ').set_corner_bottom_left('#')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1648,7 +1648,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().bottom('*').corner_bottom_right('#')),
+        Modify::new((3, 2)).with(Border::new().set_bottom('*').set_right(' ').set_corner_bottom_right('#')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1658,7 +1658,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().left('*')),
+        Modify::new((3, 2)).with(Border::new().set_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1667,7 +1667,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().corner_top_left('*')),
+        Modify::new((3, 2)).with(Border::new().set_top(' ').set_left(' ').set_corner_top_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1677,7 +1677,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().left('#').corner_top_left('*')),
+        Modify::new((3, 2)).with(Border::new().set_left('#').set_top(' ').set_corner_top_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1687,7 +1687,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().left('#').corner_bottom_left('@').corner_top_left('*')),
+        Modify::new((3, 2)).with(Border::new().set_left('#').set_top(' ').set_bottom(' ').set_corner_bottom_left('@').set_corner_top_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1698,7 +1698,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().right('*')),
+        Modify::new((3, 2)).with(Border::new().set_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1707,7 +1707,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().corner_top_right('*')),
+        Modify::new((3, 2)).with(Border::new().set_top(' ').set_right(' ').set_corner_top_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1717,7 +1717,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().right('#').corner_top_right('*')),
+        Modify::new((3, 2)).with(Border::new().set_top(' ').set_right('#').set_corner_top_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1727,7 +1727,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().right('#').corner_top_right('*').corner_bottom_right('@')),
+        Modify::new((3, 2)).with(Border::new().set_top(' ').set_bottom(' ').set_right('#').set_corner_top_right('*').set_corner_bottom_right('@')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1738,7 +1738,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((3, 2)).with(Border::default().right('#').corner_top_right('*').corner_bottom_left('@')),
+        Modify::new((3, 2)).with(Border::new().set_top(' ').set_bottom(' ').set_left(' ').set_right('#').set_corner_top_right('*').set_corner_bottom_left('@')),
         static_table!(
             " N     column 0       column 1   column 2 "
             " 0  a longer string     0-1        0-2    "
@@ -1761,7 +1761,7 @@ fn test_default_border_usage() {
     }
 
     test_border! {
-        Modify::new((1, 2)).with(Border::default().corner_bottom_left('*')),
+        Modify::new((1, 2)).with(Border::new().set_left(' ').set_bottom(' ').set_corner_bottom_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1771,7 +1771,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().corner_bottom_right('*')),
+        Modify::new((1, 2)).with(Border::new().set_right(' ').set_bottom(' ').set_corner_bottom_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1781,7 +1781,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().bottom('*')),
+        Modify::new((1, 2)).with(Border::new().set_bottom('*')),
         static_table!(
             " N     column 0      column 1  column 2 "
             " 0  a longer string    0-1       0-2    "
@@ -1791,7 +1791,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().bottom('*').corner_bottom_left('#')),
+        Modify::new((1, 2)).with(Border::new().set_left(' ').set_bottom('*').set_corner_bottom_left('#')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string     0-1       0-2    "
@@ -1801,7 +1801,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().bottom('*').corner_bottom_right('#')),
+        Modify::new((1, 2)).with(Border::new().set_right(' ').set_bottom('*').set_corner_bottom_right('#')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1811,7 +1811,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().left('*')),
+        Modify::new((1, 2)).with(Border::new().set_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             " 0  a longer string *   0-1       0-2    "
@@ -1820,7 +1820,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().corner_top_left('*')),
+        Modify::new((1, 2)).with(Border::new().set_top(' ').set_left(' ').set_corner_top_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             "                    *                    "
@@ -1830,7 +1830,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().left('#').corner_top_left('*')),
+        Modify::new((1, 2)).with(Border::new().set_left('#').set_top(' ').set_corner_top_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             "                    *                    "
@@ -1840,7 +1840,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().left('#').corner_bottom_left('@').corner_top_left('*')),
+        Modify::new((1, 2)).with(Border::new().set_top(' ').set_bottom(' ').set_left('#').set_corner_bottom_left('@').set_corner_top_left('*')),
         static_table!(
             " N     column 0       column 1  column 2 "
             "                    *                    "
@@ -1851,7 +1851,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().right('*')),
+        Modify::new((1, 2)).with(Border::new().set_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             " 0  a longer string    0-1    *   0-2    "
@@ -1860,7 +1860,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().corner_top_right('*')),
+        Modify::new((1, 2)).with(Border::new().set_top(' ').set_right(' ').set_corner_top_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             "                              *          "
@@ -1870,7 +1870,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().right('#').corner_top_right('*')),
+        Modify::new((1, 2)).with(Border::new().set_top(' ').set_right('#').set_corner_top_right('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             "                              *          "
@@ -1880,7 +1880,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().right('#').corner_top_right('*').corner_bottom_right('@')),
+        Modify::new((1, 2)).with(Border::new().set_top(' ').set_bottom(' ').set_right('#').set_corner_top_right('*').set_corner_bottom_right('@')),
         static_table!(
             " N     column 0      column 1   column 2 "
             "                              *          "
@@ -1891,7 +1891,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((1, 2)).with(Border::default().right('#').corner_top_right('*').corner_bottom_left('@')),
+        Modify::new((1, 2)).with(Border::new().set_top(' ').set_bottom(' ').set_left(' ').set_right('#').set_corner_top_right('*').set_corner_bottom_left('@')),
         static_table!(
             " N     column 0       column 1   column 2 "
             "                               *          "
@@ -1914,7 +1914,7 @@ fn test_default_border_usage() {
     }
 
     test_border! {
-        Modify::new((0, 3)).with(Border::default().corner_bottom_left('*')),
+        Modify::new((0, 3)).with(Border::new().set_left(' ').set_bottom(' ').set_corner_bottom_left('*')),
         static_table!(
             " N     column 0      column 1   column 2 "
             "                              *          "
@@ -1924,7 +1924,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().corner_bottom_right('*')),
+        Modify::new((0, 3)).with(Border::new().set_right(' ').set_bottom(' ').set_corner_bottom_right('*')),
         static_table!(
             " N     column 0      column 1  column 2  "
             "                                        *"
@@ -1934,7 +1934,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().bottom('*')),
+        Modify::new((0, 3)).with(Border::new().set_bottom('*')),
         static_table!(
             " N     column 0      column 1  column 2 "
             "                              **********"
@@ -1944,7 +1944,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().bottom('*').corner_bottom_left('#')),
+        Modify::new((0, 3)).with(Border::new().set_left(' ').set_bottom('*').set_corner_bottom_left('#')),
         static_table!(
             " N     column 0      column 1   column 2 "
             "                              #**********"
@@ -1954,7 +1954,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().bottom('*').corner_bottom_right('#')),
+        Modify::new((0, 3)).with(Border::new().set_right(' ').set_bottom('*').set_corner_bottom_right('#')),
         static_table!(
             " N     column 0      column 1  column 2  "
             "                              **********#"
@@ -1964,7 +1964,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().left('*')),
+        Modify::new((0, 3)).with(Border::new().set_left('*')),
         static_table!(
             " N     column 0      column 1 * column 2 "
             " 0  a longer string    0-1        0-2    "
@@ -1973,7 +1973,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().corner_top_left('*')),
+        Modify::new((0, 3)).with(Border::new().set_top(' ').set_left(' ').set_corner_top_left('*')),
         static_table!(
             "                              *          "
             " N     column 0      column 1   column 2 "
@@ -1983,7 +1983,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().left('#').corner_top_left('*')),
+        Modify::new((0, 3)).with(Border::new().set_top(' ').set_left('#').set_corner_top_left('*')),
         static_table!(
             "                              *          "
             " N     column 0      column 1 # column 2 "
@@ -1993,7 +1993,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().left('#').corner_bottom_left('@').corner_top_left('*')),
+        Modify::new((0, 3)).with(Border::new().set_top(' ').set_bottom(' ').set_left('#').set_corner_bottom_left('@').set_corner_top_left('*')),
         static_table!(
             "                              *          "
             " N     column 0      column 1 # column 2 "
@@ -2004,7 +2004,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().right('*')),
+        Modify::new((0, 3)).with(Border::new().set_right('*')),
         static_table!(
             " N     column 0      column 1  column 2 *"
             " 0  a longer string    0-1       0-2     "
@@ -2013,7 +2013,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().corner_top_right('*')),
+        Modify::new((0, 3)).with(Border::new().set_top(' ').set_right(' ').set_corner_top_right('*')),
         static_table!(
             "                                        *"
             " N     column 0      column 1  column 2  "
@@ -2023,7 +2023,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().right('#').corner_top_right('*')),
+        Modify::new((0, 3)).with(Border::new().set_top(' ').set_right('#').set_corner_top_right('*')),
         static_table!(
             "                                        *"
             " N     column 0      column 1  column 2 #"
@@ -2033,7 +2033,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().right('#').corner_top_right('*').corner_bottom_right('@')),
+        Modify::new((0, 3)).with(Border::new().set_top(' ').set_bottom(' ').set_right('#').set_corner_top_right('*').set_corner_bottom_right('@')),
         static_table!(
             "                                        *"
             " N     column 0      column 1  column 2 #"
@@ -2044,7 +2044,7 @@ fn test_default_border_usage() {
         )
     }
     test_border! {
-        Modify::new((0, 3)).with(Border::default().right('#').corner_top_right('*').corner_bottom_left('@')),
+        Modify::new((0, 3)).with(Border::new().set_top(' ').set_bottom(' ').set_left(' ').set_right('#').set_corner_top_right('*').set_corner_bottom_left('@')),
         static_table!(
             "                                         *"
             " N     column 0      column 1   column 2 #"
@@ -2076,9 +2076,9 @@ fn border_colored_test() {
             Modify::new(Rows::single(1))
                 .with(
                     BorderColor::filled(Color::try_from('*'.blue().to_string()).unwrap())
-                        .top(Color::try_from('#'.truecolor(12, 220, 100).to_string()).unwrap()),
+                        .set_top(Color::try_from('#'.truecolor(12, 220, 100).to_string()).unwrap()),
                 )
-                .with(Border::filled('*').top('#')),
+                .with(Border::filled('*').set_top('#')),
         )
         .to_string();
 
@@ -2114,9 +2114,9 @@ fn border_colored_test() {
             Modify::new(Rows::single(1))
                 .with(
                     BorderColor::filled(Color::try_from('*'.blue().to_string()).unwrap())
-                        .top(Color::try_from('#'.truecolor(12, 220, 100).to_string()).unwrap()),
+                        .set_top(Color::try_from('#'.truecolor(12, 220, 100).to_string()).unwrap()),
                 )
-                .with(Border::filled('*').top('#')),
+                .with(Border::filled('*').set_top('#')),
         )
         .to_string();
 
@@ -2219,7 +2219,7 @@ test_table!(
 test_table!(
     verticals_0,
     Matrix::new(3, 3)
-        .with(Style::rounded().verticals(vec![VerticalLine::new(0, Line::filled('+')), VerticalLine::new(4, Line::filled('+'))])),
+        .with(Style::rounded().verticals([(0, VerticalLine::filled('+').remove_intersection()), (4, VerticalLine::filled('+').remove_intersection())])),
     "+───┬──────────┬──────────┬──────────+"
     "+ N │ column 0 │ column 1 │ column 2 +"
     "├───┼──────────┼──────────┼──────────┤"
@@ -2231,8 +2231,13 @@ test_table!(
 
 test_table!(
     verticals_1,
-    Matrix::new(3, 3)
-        .with(Style::rounded().verticals((1..4).map(|i| VerticalLine::new(i, Line::filled('+'))))),
+    {
+        let verticals = (1..4).map(|i| (i, VerticalLine::filled('+').into_inner())).collect::<HashMap<_, _>>();
+        let mut style = RawStyle::from(Style::rounded());
+        style.set_verticals(verticals);
+
+        Matrix::new(3, 3).with(style)
+    },
     "╭───+──────────+──────────+──────────╮"
     "│ N + column 0 + column 1 + column 2 │"
     "├───┼──────────┼──────────┼──────────┤"
@@ -2244,7 +2249,7 @@ test_table!(
 
 test_table!(
     verticals_2,
-    Matrix::new(3, 3).with(Style::rounded().verticals(vec![VerticalLine::new(1, Line::filled('+'))])),
+    Matrix::new(3, 3).with(Style::rounded().verticals([(1, VerticalLine::filled('+').remove_intersection())])),
     "╭───+──────────┬──────────┬──────────╮"
     "│ N + column 0 │ column 1 │ column 2 │"
     "├───┼──────────┼──────────┼──────────┤"
@@ -2256,7 +2261,7 @@ test_table!(
 
 test_table!(
     verticals_3,
-    Matrix::new(3, 3).with(Style::ascii().verticals([VerticalLine::new(1, Line::filled('*'))])),
+    Matrix::new(3, 3).with(Style::ascii().verticals([(1, VerticalLine::filled('*'))])),
     "+---*----------+----------+----------+"
     "| N * column 0 | column 1 | column 2 |"
     "+---*----------+----------+----------+"
@@ -2270,7 +2275,13 @@ test_table!(
 
 test_table!(
     verticals_4,
-    Matrix::new(3, 3).with(Style::ascii().verticals((0..10).map(|i| VerticalLine::new(i, Line::new(Some('*'), Some('x'), Some('c'), Some('2')))))),
+    {
+        let mut style = RawStyle::from(Style::ascii());
+        let verticals = (0..10).map(|i| (i, VerticalLine::full('*', 'c', '2', 'x').into_inner())).collect();
+        style.set_verticals(verticals);
+
+        Matrix::new(3, 3).with(style)
+    },
     "c---c----------c----------c----------c"
     "* N * column 0 * column 1 * column 2 *"
     "x---x----------x----------x----------x"
@@ -2284,9 +2295,15 @@ test_table!(
 
 test_table!(
     vertical_line_0,
-    Matrix::new(3, 3)
-        .with(HorizontalLine::new(1, Line::new(Some('8'), Some('8'), Some('8'), Some('8'))))
-        .with(VerticalLine::new(1, Line::new(Some('*'), Some('x'), Some('c'), Some('2')))),
+    {
+        let m = Matrix::new(3, 3);
+
+        let mut style = RawStyle::from(Style::ascii());
+        style.insert_horizontal(1, Line::full('8', '8', '8', '8'));
+        style.insert_vertical(1, Line::full('*', 'x', 'c', '2'));
+
+        m.with(style)
+    },
     "+---c----------+----------+----------+"
     "| N * column 0 | column 1 | column 2 |"
     "88888888888888888888888888888888888888"
@@ -2298,37 +2315,15 @@ test_table!(
     "+---2----------+----------+----------+"
 );
 
-test_table!(
-    vertical_line_1,
-    Matrix::new(3, 3)
-        .with(Style::empty())
-        .with(VerticalLine::new(1, Line::new(Some('*'), Some('x'), Some('c'), Some('2')))),
-    "   c                              "
-    " N * column 0  column 1  column 2 "
-    " 0 *   0-0       0-1       0-2    "
-    " 1 *   1-0       1-1       1-2    "
-    " 2 *   2-0       2-1       2-2    "
-    "   2                              "
-);
+// todo: StyleFromTable()
+//       table.with(&mut StyleFromTable);
+// even better RawStyle::from()
+// todo Add a example for it...
 
 test_table!(
-    vertical_line_2,
-    Matrix::new(3, 3)
-        .with(Style::empty())
-        .with(VerticalLine::new(1, Line::new(None, Some('x'), Some('c'), Some('2')))),
-    "   c                              "
-    " N   column 0  column 1  column 2 "
-    " 0     0-0       0-1       0-2    "
-    " 1     1-0       1-1       1-2    "
-    " 2     2-0       2-1       2-2    "
-    "   2                              "
-);
-
-test_table!(
-    vertical_line_3,
+    vertical_line_1,
     Matrix::new(3, 3)
-        .with(Style::empty())
-        .with(VerticalLine::new(1, Line::new(Some('*'), Some('x'), None, None))),
+        .with(Style::empty().verticals([(1, VerticalLine::new('*'))])),
     " N * column 0  column 1  column 2 "
     " 0 *   0-0       0-1       0-2    "
     " 1 *   1-0       1-1       1-2    "
@@ -2340,8 +2335,8 @@ test_table!(
     Matrix::new(3, 3)
         .with(Style::markdown())
         .with(Modify::new(Rows::single(1))
-            .with(BorderChar::horizontal(':', Offset::Begin(0)))
-            .with(BorderChar::horizontal(':', Offset::End(0)))
+            .with(LineChar::horizontal(':', Offset::Begin(0)))
+            .with(LineChar::horizontal(':', Offset::End(0)))
     ),
     "| N | column 0 | column 1 | column 2 |"
     "|:-:|:--------:|:--------:|:--------:|"
@@ -2354,10 +2349,10 @@ test_table!(
     override_horizontal_border_on_borders,
     Matrix::new(3, 3)
         .with(Modify::new(Rows::new(..5))
-            .with(BorderChar::horizontal(':', Offset::Begin(0)))
-            .with(BorderChar::horizontal('y', Offset::Begin(3)))
-            .with(BorderChar::horizontal(':', Offset::End(0)))
-            .with(BorderChar::horizontal('x', Offset::End(3)))
+            .with(LineChar::horizontal(':', Offset::Begin(0)))
+            .with(LineChar::horizontal('y', Offset::Begin(3)))
+            .with(LineChar::horizontal(':', Offset::End(0)))
+            .with(LineChar::horizontal('x', Offset::End(3)))
     ),
     "+:-:+:--y--x--:+:--y--x--:+:--y--x--:+"
     "| N | column 0 | column 1 | column 2 |"
@@ -2375,10 +2370,10 @@ test_table!(
     Matrix::new(3, 3)
         .with(Modify::new(Rows::new(..5))
             .with(Border::filled('['))
-            .with(BorderChar::horizontal(':', Offset::Begin(0)))
-            .with(BorderChar::horizontal('y', Offset::Begin(3)))
-            .with(BorderChar::horizontal(':', Offset::End(0)))
-            .with(BorderChar::horizontal('x', Offset::End(3)))
+            .with(LineChar::horizontal(':', Offset::Begin(0)))
+            .with(LineChar::horizontal('y', Offset::Begin(3)))
+            .with(LineChar::horizontal(':', Offset::End(0)))
+            .with(LineChar::horizontal('x', Offset::End(3)))
     ),
     "[:[:[:[[y[[x[[:[:[[y[[x[[:[:[[y[[x[[:["
     "[ N [ column 0 [ column 1 [ column 2 ["
@@ -2396,7 +2391,7 @@ test_table!(
     Matrix::new(3, 3)
         .with(Style::markdown())
         .with(Modify::new(Columns::single(1))
-            .with(BorderChar::vertical(':', Offset::Begin(0)))
+            .with(LineChar::vertical(':', Offset::Begin(0)))
     ),
     "| N : column 0 | column 1 | column 2 |"
     "|---|----------|----------|----------|"
@@ -2410,7 +2405,7 @@ test_table!(
     Matrix::new(3, 3)
         .with(Style::markdown())
         .with(Modify::new(Columns::single(1))
-            .with(BorderChar::vertical(':', Offset::End(0)))
+            .with(LineChar::vertical(':', Offset::End(0)))
     ),
     "| N : column 0 | column 1 | column 2 |"
     "|---|----------|----------|----------|"
@@ -2425,7 +2420,7 @@ test_table!(
         .with(Modify::new(Rows::single(1)).with(Format::content(|s| format!("\nsome text\ntext\n{s}\ntext\ntext\n"))))
         .with(Style::markdown())
         .with(Modify::new(Columns::single(1))
-            .with(BorderChar::vertical(':', Offset::Begin(4)))
+            .with(LineChar::vertical(':', Offset::Begin(4)))
     ),
     "|     N     | column 0  | column 1  | column 2  |"
     "|-----------|-----------|-----------|-----------|"
@@ -2446,7 +2441,7 @@ test_table!(
         .with(Modify::new(Rows::single(1)).with(Format::content(|s| format!("\nsome text\ntext\n{s}\ntext\ntext\n"))))
         .with(Style::markdown())
         .with(Modify::new(Columns::single(1))
-            .with(BorderChar::vertical(':', Offset::End(4)))
+            .with(LineChar::vertical(':', Offset::End(4)))
     ),
     "|     N     | column 0  | column 1  | column 2  |"
     "|-----------|-----------|-----------|-----------|"
@@ -2467,12 +2462,12 @@ test_table!(
         .with(Modify::new(Rows::single(1)).with(Format::content(|s| format!("\nsome text\ntext\n{s}\ntext\ntext\n"))))
         .with(Style::markdown())
         .with(Modify::new(Columns::new(..5))
-            .with(BorderChar::vertical('y', Offset::Begin(0)))
-            .with(BorderChar::vertical('^', Offset::End(0)))
+            .with(LineChar::vertical('y', Offset::Begin(0)))
+            .with(LineChar::vertical('^', Offset::End(0)))
         )
         .with(Modify::new(Rows::single(1))
-            .with(BorderChar::horizontal('x', Offset::Begin(0)))
-            .with(BorderChar::horizontal('@', Offset::End(0)))
+            .with(LineChar::horizontal('x', Offset::Begin(0)))
+            .with(LineChar::horizontal('@', Offset::End(0)))
         ),
     "y     N     y column 0  y column 1  y column 2  y"
     "|x---------@|x---------@|x---------@|x---------@|"
@@ -2622,9 +2617,9 @@ test_table!(
 test_table!(
     style_const_modification,
     {
-        const STYLE: Style<On, On, On, On, On, On, [HorizontalLine; 1]> = Style::ascii()
+        const STYLE: Style<On, On, On, On, On, On, 1, 0> = Style::ascii()
             .bottom('x')
-            .horizontals([HorizontalLine::new(1, Line::filled('.'))]);
+            .horizontals([(1, HorizontalLine::filled('.'))]);
         Matrix::new(3, 3).with(STYLE)
     },
     "+---+----------+----------+----------+"
@@ -2641,10 +2636,10 @@ test_table!(
 test_table!(
     style_static_modification,
     {
-        static STYLE: Style<On, On, On, On, On, On, [HorizontalLine; 1], [VerticalLine; 1]> = Style::ascii()
+        static STYLE: Style<On, On, On, On, On, On, 1, 1> = Style::ascii()
             .bottom('x')
-            .horizontals([HorizontalLine::new(1, Line::filled('.'))])
-            .verticals([VerticalLine::new(1, Line::filled('|'))]);
+            .horizontals([(1, HorizontalLine::filled('.'))])
+            .verticals([(1, VerticalLine::filled('|'))]);
         Matrix::new(3, 3).with(STYLE.clone())
     },
     "+---|----------+----------+----------+"
diff --git a/tabled/tests/settings/width_test.rs b/tabled/tests/settings/width_test.rs
index d2bc84a..90d8d86 100644
--- a/tabled/tests/settings/width_test.rs
+++ b/tabled/tests/settings/width_test.rs
@@ -405,8 +405,6 @@ fn max_width_wrapped_keep_words_long_word_color() {
 #[cfg(feature = "color")]
 #[test]
 fn max_width_keep_words_1() {
-    use tabled::settings::style::HorizontalLine;
-
     let table = Matrix::iter(["asdf"])
         .with(Width::wrap(7).keep_words())
         .to_string();
@@ -449,7 +447,7 @@ fn max_width_keep_words_1() {
     .with(
         Style::modern()
             .remove_horizontal()
-            .horizontals([HorizontalLine::new(1, Style::modern().get_horizontal())]),
+            .horizontals([(1, Style::modern().get_horizontal_line())]),
     )
     .with(Width::wrap(21).keep_words().priority::<PriorityMax>())
     .with(Alignment::center())