Repository: zhiburt/tabled
Pull request #334 (2023-04-22 23:54:34)

Refactorings interface 0.11.1


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40c004a..9f3d02a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
+## [0.12.0] - 2023-04-23
+
+### Added
+
+### Changed
+
+- Made a list of changes to `tabled` .
+- Made a list of changes to `papergrid` interface.
+
+### Fixed
+
+- Fixed `PoolTable` vertical intersection issue.
+
 ## [0.11.0] - 2023-04-12
 
 ### Added
diff --git a/csv_to_table/Cargo.toml b/csv_to_table/Cargo.toml
index 62617ea..a244074 100644
--- a/csv_to_table/Cargo.toml
+++ b/csv_to_table/Cargo.toml
@@ -17,4 +17,4 @@ color = ["tabled/color"]
 
 [dependencies]
 csv = "1"
-tabled = { version = "0.11", features = ["std"], default-features = false }
+tabled = { path = "../tabled", features = ["std"], default-features = false }
diff --git a/json_to_table/Cargo.toml b/json_to_table/Cargo.toml
index 2c77448..6db193e 100644
--- a/json_to_table/Cargo.toml
+++ b/json_to_table/Cargo.toml
@@ -17,4 +17,4 @@ color = ["tabled/color"]
 
 [dependencies]
 serde_json = "1"
-tabled = { version = "0.11", features = ["macros"], default-features = false }
+tabled = { path = "../tabled", features = ["macros"], default-features = false }
diff --git a/json_to_table/src/table/collapsed_table.rs b/json_to_table/src/table/collapsed_table.rs
index 30ff787..ab7e50f 100644
--- a/json_to_table/src/table/collapsed_table.rs
+++ b/json_to_table/src/table/collapsed_table.rs
@@ -316,7 +316,7 @@ fn generate_vertical_object(
         let key = config_string(key, &cfg.cfg, max_key_width, entry_height);
 
         let mut key = col![key];
-        key.with(&cfg.cfg);
+        key.with(cfg.cfg.clone());
         key.with(NoRightBorders);
 
         if !is_last_row {
@@ -515,7 +515,7 @@ fn generate_value_cell(value: &str, cfg: &Config, ctx: PrintContext) -> CellData
     let value = config_string(value, &cfg.cfg, ctx.size.width, ctx.size.height);
 
     let mut table = col![value];
-    table.with(&cfg.cfg);
+    table.with(cfg.cfg.clone());
 
     if !ctx.is_last_row || ctx.no_bottom {
         table.with(NoBottomBorders);
@@ -589,7 +589,7 @@ fn generate_value_cell(value: &str, cfg: &Config, ctx: PrintContext) -> CellData
 struct NoTopBorders;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for NoTopBorders {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top = None;
         borders.top_intersection = None;
@@ -603,7 +603,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoTopBorders {
 struct NoBottomBorders;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for NoBottomBorders {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom = None;
         borders.bottom_intersection = None;
@@ -617,7 +617,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoBottomBorders {
 struct NoRightBorders;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for NoRightBorders {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_right = None;
         borders.bottom_right = None;
@@ -631,7 +631,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoRightBorders {
 struct NoLeftBorders;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for NoLeftBorders {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = None;
         borders.bottom_left = None;
@@ -645,7 +645,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoLeftBorders {
 struct TopLeftChangeTopIntersection;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeTopIntersection {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = borders.top_intersection;
 
@@ -656,7 +656,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeTopIntersection {
 struct TopLeftChangeIntersection;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeIntersection {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = borders.intersection;
 
@@ -667,7 +667,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeIntersection {
 struct TopLeftChangeToLeft;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeToLeft {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = borders.left_intersection;
 
@@ -678,7 +678,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeToLeft {
 struct TopRightChangeToRight;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for TopRightChangeToRight {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_right = borders.right_intersection;
 
@@ -689,7 +689,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopRightChangeToRight {
 struct BottomLeftChangeSplit;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplit {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_left = borders.left_intersection;
 
@@ -700,7 +700,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplit {
 struct BottomLeftChangeSplitToIntersection;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplitToIntersection {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_left = borders.intersection;
 
@@ -711,7 +711,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplitToIntersect
 struct BottomRightChangeToRight;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for BottomRightChangeToRight {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_right = borders.right_intersection;
 
@@ -722,7 +722,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BottomRightChangeToRight {
 struct BottomLeftChangeToBottomIntersection;
 
 impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeToBottomIntersection {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_left = borders.bottom_intersection;
 
@@ -738,7 +738,7 @@ where
     for<'a> &'a R: Records,
     for<'a> D: Dimension + Estimate<&'a R, SpannedConfig>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
         dims.estimate(&*records, cfg);
 
         let table_width = (0..records.count_columns())
@@ -764,7 +764,7 @@ where
 struct SetTopChars<'a>(&'a [usize], char);
 
 impl<R, D> TableOption<R, D, ColoredConfig> for SetTopChars<'_> {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         for &split in self.0 {
             let offset = split;
             cfg.set_horizontal_char((0, 0), self.1, Offset::Begin(offset));
@@ -775,7 +775,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for SetTopChars<'_> {
 struct SetLeftChars<'a>(&'a [usize], char);
 
 impl<R, D> TableOption<R, D, ColoredConfig> for SetLeftChars<'_> {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         for &offset in self.0 {
             cfg.set_vertical_char((0, 0), self.1, Offset::Begin(offset));
         }
@@ -784,16 +784,16 @@ impl<R, D> TableOption<R, D, ColoredConfig> for SetLeftChars<'_> {
 
 struct GetTopIntersection(char);
 
-impl<R, D> TableOption<R, D, ColoredConfig> for GetTopIntersection {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetTopIntersection {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         self.0 = cfg.get_borders().top_intersection.unwrap_or(' ');
     }
 }
 
 struct GetBottomIntersection(char);
 
-impl<R, D> TableOption<R, D, ColoredConfig> for GetBottomIntersection {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetBottomIntersection {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         self.0 = cfg.get_borders().bottom_intersection.unwrap_or(' ');
     }
 }
diff --git a/json_to_table/src/table/mod.rs b/json_to_table/src/table/mod.rs
index af9fa89..081ce21 100644
--- a/json_to_table/src/table/mod.rs
+++ b/json_to_table/src/table/mod.rs
@@ -30,7 +30,7 @@ impl<T> JsonTable<T> {
             value,
             cfg: Config {
                 plain: true,
-                cfg: ColoredConfig::new(configure_grid(), Default::default()),
+                cfg: ColoredConfig::new(configure_grid()),
                 array_orientation: Orientation::Column,
                 object_orientation: Orientation::Column,
             },
@@ -108,7 +108,7 @@ impl<T> JsonTable<T> {
     /// ```
     ///
     /// [`Table`]: tabled::Table
-    pub fn with<O>(&mut self, mut option: O) -> &mut Self
+    pub fn with<O>(&mut self, option: O) -> &mut Self
     where
         O: TableOption<EmptyRecords, CompleteDimension<'static>, ColoredConfig>,
     {
diff --git a/json_to_table/src/table/plain_table.rs b/json_to_table/src/table/plain_table.rs
index f09ca29..2a35294 100644
--- a/json_to_table/src/table/plain_table.rs
+++ b/json_to_table/src/table/plain_table.rs
@@ -19,7 +19,7 @@ fn _plain_table(v: &Value, cfg: &Config, outer: bool) -> String {
                     buf.push_record([val]);
                 }
 
-                buf.build().with(&cfg.cfg).to_string()
+                buf.build().with(cfg.cfg.clone()).to_string()
             }
             Orientation::Row => {
                 let mut buf = Vec::with_capacity(arr.len());
@@ -28,7 +28,10 @@ fn _plain_table(v: &Value, cfg: &Config, outer: bool) -> String {
                     buf.push(val);
                 }
 
-                Builder::from(vec![buf]).build().with(&cfg.cfg).to_string()
+                Builder::from(vec![buf])
+                    .build()
+                    .with(cfg.cfg.clone())
+                    .to_string()
             }
         },
         Value::Object(map) => match cfg.object_orientation {
@@ -39,7 +42,7 @@ fn _plain_table(v: &Value, cfg: &Config, outer: bool) -> String {
                     buf.push_record([key.clone(), val]);
                 }
 
-                buf.build().with(&cfg.cfg).to_string()
+                buf.build().with(cfg.cfg.clone()).to_string()
             }
             Orientation::Row => {
                 let mut keys = Vec::with_capacity(map.len());
@@ -52,7 +55,7 @@ fn _plain_table(v: &Value, cfg: &Config, outer: bool) -> String {
 
                 Builder::from(vec![keys, vals])
                     .build()
-                    .with(&cfg.cfg)
+                    .with(cfg.cfg.clone())
                     .to_string()
             }
         },
@@ -66,7 +69,7 @@ fn _plain_table(v: &Value, cfg: &Config, outer: bool) -> String {
             };
 
             let mut table = Table::from_iter([[val]]);
-            table.with(&cfg.cfg);
+            table.with(cfg.cfg.clone());
 
             if !outer {
                 table.with(Style::empty());
diff --git a/papergrid/src/color/ansi_color.rs b/papergrid/src/color/ansi_color.rs
index 021e9d2..6fcf4f8 100644
--- a/papergrid/src/color/ansi_color.rs
+++ b/papergrid/src/color/ansi_color.rs
@@ -6,7 +6,7 @@ use std::{
 use super::{Color, StaticColor};
 
 /// The structure represents a ANSI color by suffix and prefix.
-#[derive(Debug, Clone, Eq, PartialEq, Default)]
+#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct AnsiColor<'a> {
     prefix: Cow<'a, str>,
     suffix: Cow<'a, str>,
diff --git a/papergrid/src/color/static_color.rs b/papergrid/src/color/static_color.rs
index b1e03a4..3f9a38c 100644
--- a/papergrid/src/color/static_color.rs
+++ b/papergrid/src/color/static_color.rs
@@ -19,6 +19,11 @@ impl StaticColor {
     pub const fn new(prefix: &'static str, suffix: &'static str) -> Self {
         Self { prefix, suffix }
     }
+
+    /// Verifies if anything was actually set.
+    pub const fn is_empty(&self) -> bool {
+        self.prefix.is_empty() && self.suffix.is_empty()
+    }
 }
 
 impl StaticColor {
diff --git a/papergrid/src/config/border.rs b/papergrid/src/config/border.rs
index 040ba25..e803900 100644
--- a/papergrid/src/config/border.rs
+++ b/papergrid/src/config/border.rs
@@ -14,7 +14,7 @@
 ///                             |
 ///                        bottom border
 /// ```
-#[derive(Debug, Clone, Default, Eq, PartialEq)]
+#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
 pub struct Border<T> {
     /// A character for a top.
     pub top: Option<T>,
@@ -70,6 +70,30 @@ impl<T> Border<T> {
             && self.left.is_none()
             && self.right.is_none()
     }
+
+    /// Verifies whether anything is set on the top.
+    pub const fn has_top(&self) -> bool {
+        self.top.is_some() || self.left_top_corner.is_some() || self.right_top_corner.is_some()
+    }
+
+    /// Verifies whether anything is set on the bottom.
+    pub const fn has_bottom(&self) -> bool {
+        self.bottom.is_some()
+            || self.left_bottom_corner.is_some()
+            || self.right_bottom_corner.is_some()
+    }
+
+    /// Verifies whether anything is set on the left.
+    pub const fn has_left(&self) -> bool {
+        self.left.is_some() || self.left_top_corner.is_some() || self.left_bottom_corner.is_some()
+    }
+
+    /// Verifies whether anything is set on the right.
+    pub const fn has_right(&self) -> bool {
+        self.right.is_some()
+            || self.right_top_corner.is_some()
+            || self.right_bottom_corner.is_some()
+    }
 }
 
 impl<T: Copy> Border<T> {
diff --git a/papergrid/src/config/spanned/formatting.rs b/papergrid/src/config/spanned/formatting.rs
index 10aceba..0865f6c 100644
--- a/papergrid/src/config/spanned/formatting.rs
+++ b/papergrid/src/config/spanned/formatting.rs
@@ -1,5 +1,5 @@
 /// Formatting represent a logic of formatting of a cell.
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Formatting {
     /// An setting to allow horizontal trim.
     pub horizontal_trim: bool,
diff --git a/papergrid/src/dimension/mod.rs b/papergrid/src/dimension/mod.rs
index ef54af0..40be17b 100644
--- a/papergrid/src/dimension/mod.rs
+++ b/papergrid/src/dimension/mod.rs
@@ -4,6 +4,8 @@
 pub mod compact;
 #[cfg(feature = "std")]
 pub mod spanned;
+#[cfg(feature = "std")]
+pub mod spanned_vec_records;
 
 /// Dimension of a [`Grid`]
 ///
diff --git a/papergrid/src/dimension/spanned_vec_records.rs b/papergrid/src/dimension/spanned_vec_records.rs
new file mode 100644
index 0000000..3825ca9
--- /dev/null
+++ b/papergrid/src/dimension/spanned_vec_records.rs
@@ -0,0 +1,332 @@
+//! The module contains a [`SpannedGridDimension`] for [`Grid`] height/width estimation.
+//!
+//! [`Grid`]: crate::grid::iterable::Grid
+
+use std::{
+    cmp::{max, Ordering},
+    collections::HashMap,
+};
+
+use crate::{
+    config::Position,
+    dimension::{Dimension, Estimate},
+    records::{
+        vec_records::{Cell, VecRecords},
+        Records,
+    },
+};
+
+use crate::config::spanned::SpannedConfig;
+
+/// A [`Dimension`] implementation which calculates exact column/row width/height for [`VecRecords`].
+///
+/// It is a specialization of [`SpannedGridDimension`] for [`VecRecords`].
+///
+/// [`SpannedGridDimension`]: crate::dimension::SpannedGridDimension
+#[derive(Debug, Default, Clone, PartialEq, Eq)]
+pub struct SpannedVecRecordsDimension {
+    height: Vec<usize>,
+    width: Vec<usize>,
+}
+
+impl SpannedVecRecordsDimension {
+    /// Calculates height of rows.
+    pub fn height<T: Cell + AsRef<str>>(
+        records: &VecRecords<T>,
+        cfg: &SpannedConfig,
+    ) -> Vec<usize> {
+        build_height(records, cfg)
+    }
+
+    /// Calculates width of columns.
+    pub fn width<T: Cell + AsRef<str>>(records: &VecRecords<T>, cfg: &SpannedConfig) -> Vec<usize> {
+        build_width(records, cfg)
+    }
+
+    /// Return width and height lists.
+    pub fn get_values(self) -> (Vec<usize>, Vec<usize>) {
+        (self.width, self.height)
+    }
+}
+
+impl Dimension for SpannedVecRecordsDimension {
+    fn get_width(&self, column: usize) -> usize {
+        self.width[column]
+    }
+
+    fn get_height(&self, row: usize) -> usize {
+        self.height[row]
+    }
+}
+
+impl<T> Estimate<&VecRecords<T>, SpannedConfig> for SpannedVecRecordsDimension
+where
+    T: Cell + AsRef<str>,
+{
+    fn estimate(&mut self, records: &VecRecords<T>, cfg: &SpannedConfig) {
+        let (width, height) = build_dimensions(records, cfg);
+        self.width = width;
+        self.height = height;
+    }
+}
+
+fn build_dimensions<T: Cell + AsRef<str>>(
+    records: &VecRecords<T>,
+    cfg: &SpannedConfig,
+) -> (Vec<usize>, Vec<usize>) {
+    let count_columns = records.count_columns();
+
+    let mut widths = vec![0; count_columns];
+    let mut heights = vec![];
+
+    let mut vspans = HashMap::new();
+    let mut hspans = HashMap::new();
+
+    for (row, columns) in records.iter_rows().enumerate() {
+        let mut row_height = 0;
+        for (col, cell) in columns.iter().enumerate() {
+            let pos = (row, col);
+            if !cfg.is_cell_visible(pos) {
+                continue;
+            }
+
+            let width = cell.width();
+            let height = cell.count_lines();
+            let pad = cfg.get_padding(pos.into());
+            let width = width + pad.left.size + pad.right.size;
+            let height = height + pad.top.size + pad.bottom.size;
+
+            match cfg.get_column_span(pos) {
+                Some(n) if n > 1 => {
+                    vspans.insert(pos, (n, width));
+                }
+                _ => widths[col] = max(widths[col], width),
+            }
+
+            match cfg.get_row_span(pos) {
+                Some(n) if n > 1 => {
+                    hspans.insert(pos, (n, height));
+                }
+                _ => row_height = max(row_height, height),
+            }
+        }
+
+        heights.push(row_height);
+    }
+
+    let count_rows = heights.len();
+
+    adjust_vspans(cfg, count_columns, &vspans, &mut widths);
+    adjust_hspans(cfg, count_rows, &hspans, &mut heights);
+
+    (widths, heights)
+}
+
+fn adjust_hspans(
+    cfg: &SpannedConfig,
+    len: usize,
+    spans: &HashMap<Position, (usize, usize)>,
+    heights: &mut [usize],
+) {
+    if spans.is_empty() {
+        return;
+    }
+
+    let mut spans_ordered = spans
+        .iter()
+        .map(|(k, v)| ((k.0, k.1), *v))
+        .collect::<Vec<_>>();
+    spans_ordered.sort_unstable_by(|(arow, acol), (brow, bcol)| match arow.cmp(brow) {
+        Ordering::Equal => acol.cmp(bcol),
+        ord => ord,
+    });
+
+    for ((row, _), (span, height)) in spans_ordered {
+        adjust_row_range(cfg, height, len, row, row + span, heights);
+    }
+}
+
+fn adjust_row_range(
+    cfg: &SpannedConfig,
+    max_span_height: usize,
+    len: usize,
+    start: usize,
+    end: usize,
+    heights: &mut [usize],
+) {
+    let range_height = range_height(cfg, len, start, end, heights);
+    if range_height >= max_span_height {
+        return;
+    }
+
+    inc_range(heights, max_span_height - range_height, start, end);
+}
+
+fn range_height(
+    cfg: &SpannedConfig,
+    len: usize,
+    start: usize,
+    end: usize,
+    heights: &[usize],
+) -> usize {
+    let count_borders = count_horizontal_borders(cfg, len, start, end);
+    let range_height = heights[start..end].iter().sum::<usize>();
+    count_borders + range_height
+}
+
+fn count_horizontal_borders(cfg: &SpannedConfig, len: usize, start: usize, end: usize) -> usize {
+    (start..end)
+        .skip(1)
+        .filter(|&i| cfg.has_horizontal(i, len))
+        .count()
+}
+
+fn inc_range(list: &mut [usize], size: usize, start: usize, end: usize) {
+    if list.is_empty() {
+        return;
+    }
+
+    let span = end - start;
+    let one = size / span;
+    let rest = size - span * one;
+
+    let mut i = start;
+    while i < end {
+        if i == start {
+            list[i] += one + rest;
+        } else {
+            list[i] += one;
+        }
+
+        i += 1;
+    }
+}
+
+fn adjust_vspans(
+    cfg: &SpannedConfig,
+    len: usize,
+    spans: &HashMap<Position, (usize, usize)>,
+    widths: &mut [usize],
+) {
+    if spans.is_empty() {
+        return;
+    }
+
+    // The overall width distribution will be different depend on the order.
+    //
+    // We sort spans in order to prioritize the smaller spans first.
+    let mut spans_ordered = spans
+        .iter()
+        .map(|(k, v)| ((k.0, k.1), *v))
+        .collect::<Vec<_>>();
+    spans_ordered.sort_unstable_by(|a, b| match a.1 .0.cmp(&b.1 .0) {
+        Ordering::Equal => a.0.cmp(&b.0),
+        o => o,
+    });
+
+    for ((_, col), (span, width)) in spans_ordered {
+        adjust_column_range(cfg, width, len, col, col + span, widths);
+    }
+}
+
+fn adjust_column_range(
+    cfg: &SpannedConfig,
+    max_span_width: usize,
+    len: usize,
+    start: usize,
+    end: usize,
+    widths: &mut [usize],
+) {
+    let range_width = range_width(cfg, len, start, end, widths);
+    if range_width >= max_span_width {
+        return;
+    }
+
+    inc_range(widths, max_span_width - range_width, start, end);
+}
+
+fn get_cell_padding_horizontal(cfg: &SpannedConfig, pos: Position) -> usize {
+    let padding = cfg.get_padding(pos.into());
+    padding.left.size + padding.right.size
+}
+
+fn get_cell_vertical_padding(cfg: &SpannedConfig, pos: Position) -> usize {
+    let padding = cfg.get_padding(pos.into());
+    padding.top.size + padding.bottom.size
+}
+
+fn range_width(
+    cfg: &SpannedConfig,
+    len: usize,
+    start: usize,
+    end: usize,
+    widths: &[usize],
+) -> usize {
+    let count_borders = count_vertical_borders(cfg, len, start, end);
+    let range_width = widths[start..end].iter().sum::<usize>();
+    count_borders + range_width
+}
+
+fn count_vertical_borders(cfg: &SpannedConfig, len: usize, start: usize, end: usize) -> usize {
+    (start..end)
+        .skip(1)
+        .filter(|&i| cfg.has_vertical(i, len))
+        .count()
+}
+
+fn build_height<T: Cell + AsRef<str>>(records: &VecRecords<T>, cfg: &SpannedConfig) -> Vec<usize> {
+    let mut heights = vec![];
+    let mut hspans = HashMap::new();
+
+    for (row, columns) in records.iter_rows().enumerate() {
+        let mut row_height = 0;
+        for (col, cell) in columns.iter().enumerate() {
+            let pos = (row, col);
+            if !cfg.is_cell_visible(pos) {
+                continue;
+            }
+
+            let height = cell.count_lines() + get_cell_vertical_padding(cfg, pos);
+            match cfg.get_row_span(pos) {
+                Some(n) if n > 1 => {
+                    hspans.insert(pos, (n, height));
+                }
+                _ => row_height = max(row_height, height),
+            }
+        }
+
+        heights.push(row_height);
+    }
+
+    adjust_hspans(cfg, heights.len(), &hspans, &mut heights);
+
+    heights
+}
+
+fn build_width<T: Cell + AsRef<str>>(records: &VecRecords<T>, cfg: &SpannedConfig) -> Vec<usize> {
+    let count_columns = records.count_columns();
+
+    let mut widths = vec![0; count_columns];
+    let mut vspans = HashMap::new();
+
+    for (row, columns) in records.iter_rows().enumerate() {
+        for (col, cell) in columns.iter().enumerate() {
+            let pos = (row, col);
+            if !cfg.is_cell_visible(pos) {
+                continue;
+            }
+
+            let width = cell.width() + get_cell_padding_horizontal(cfg, (row, col));
+            match cfg.get_column_span(pos) {
+                Some(n) if n > 1 => {
+                    vspans.insert(pos, (n, width));
+                }
+                _ => widths[col] = max(widths[col], width),
+            }
+        }
+    }
+
+    adjust_vspans(cfg, count_columns, &vspans, &mut widths);
+
+    widths
+}
diff --git a/papergrid/src/records/vec_records/cell_info.rs b/papergrid/src/records/vec_records/cell_info.rs
index 547d5e9..d9b0ed7 100644
--- a/papergrid/src/records/vec_records/cell_info.rs
+++ b/papergrid/src/records/vec_records/cell_info.rs
@@ -22,6 +22,11 @@ impl<S> CellInfo<S> {
         create_cell_info(text)
     }
 
+    /// Creates a new instance of the structure with a single line.
+    pub fn exact(text: S, width: usize, lines: Vec<StrWithWidth<'static>>) -> Self {
+        Self { text, width, lines }
+    }
+
     /// Return a original text value.
     pub fn into_inner(self) -> S {
         self.text
@@ -109,14 +114,16 @@ where
     }
 }
 
+/// StrWithWidth is a structure is responsible for a string and it's width.
 #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone)]
-struct StrWithWidth<'a> {
+pub struct StrWithWidth<'a> {
     text: Cow<'a, str>,
     width: usize,
 }
 
 impl<'a> StrWithWidth<'a> {
-    fn new(text: Cow<'a, str>, width: usize) -> Self {
+    /// Creates a new object.
+    pub fn new(text: Cow<'a, str>, width: usize) -> Self {
         Self { text, width }
     }
 }
diff --git a/papergrid/src/records/vec_records/mod.rs b/papergrid/src/records/vec_records/mod.rs
index b4dcb1f..279eb3a 100644
--- a/papergrid/src/records/vec_records/mod.rs
+++ b/papergrid/src/records/vec_records/mod.rs
@@ -12,7 +12,7 @@ use std::ops::{Deref, DerefMut};
 use super::PeekableRecords;
 
 pub use cell::Cell;
-pub use cell_info::CellInfo;
+pub use cell_info::{CellInfo, StrWithWidth};
 
 /// A [Records] implementation based on allocated buffers.
 #[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
diff --git a/ron_to_table/Cargo.toml b/ron_to_table/Cargo.toml
index bcb9cd2..613a719 100644
--- a/ron_to_table/Cargo.toml
+++ b/ron_to_table/Cargo.toml
@@ -17,4 +17,4 @@ color = ["tabled/color"]
 
 [dependencies]
 ron = "0.8"
-tabled = { version = "0.11", features = ["std"], default-features = false }
+tabled = { path = "../tabled", features = ["std"], default-features = false }
diff --git a/ron_to_table/src/table.rs b/ron_to_table/src/table.rs
index edd6008..cd115ba 100644
--- a/ron_to_table/src/table.rs
+++ b/ron_to_table/src/table.rs
@@ -68,7 +68,7 @@ impl RonTable {
     }
 
     /// Apply settings to the table.
-    pub fn with<O>(&mut self, mut option: O) -> &mut Self
+    pub fn with<O>(&mut self, option: O) -> &mut Self
     where
         O: TableOption<EmptyRecords, CompleteDimension<'static>, CompactMultilineConfig>,
     {
diff --git a/static_table/Cargo.toml b/static_table/Cargo.toml
index f1e317e..58e6aca 100644
--- a/static_table/Cargo.toml
+++ b/static_table/Cargo.toml
@@ -18,7 +18,7 @@ proc-macro = true
 color = ["tabled/color"]
 
 [dependencies]
-tabled = { version = "0.11", features = ["std"], default-features = false }
+tabled = { path = "../tabled", features = ["std"], default-features = false }
 syn = { version = "1", features = ["parsing"] }
 quote = "1"
 proc-macro2 = "1"
diff --git a/static_table/README.md b/static_table/README.md
index c98b545..2537dce 100644
--- a/static_table/README.md
+++ b/static_table/README.md
@@ -4,7 +4,7 @@ The library provides a macros to build a pretty tables at compile time.
 
 To find a few features and settings which you can use with the macros please check out the documentation ([docs.rs](https://docs.rs/static_table)).
 
-### Get started
+## Get started
 
 
 <table>
@@ -114,3 +114,19 @@ pub fn add(left: usize, right: usize) -> usize {
     left + right
 }
 ```
+
+## Binary size concern
+
+It's something you shall be aware of.
+Using `static_table` MIGHT increase a binary size, because the table will be stored as actuall symbols in a static section of a binary file (ELF, PE etc.).
+
+I have run a few tests in this regard.
+And a binary which used `static_table` has SUBSTATIANALY smaller size than
+a binary with a build table at runtime using `lazy_static`/`once_cell`.
+I am not sure though why it is a case.
+
+```table
+                debug mode      release mode
+static_table    13497232        4501576
+runtime table   12031120        4156024
+```
\ No newline at end of file
diff --git a/table_to_html/Cargo.toml b/table_to_html/Cargo.toml
index e5be7f9..7dbab07 100644
--- a/table_to_html/Cargo.toml
+++ b/table_to_html/Cargo.toml
@@ -8,7 +8,7 @@ repository = "https://github.com/zhiburt/tabled"
 license = "MIT"
 
 [dependencies]
-tabled = { version = "0.11", features = ["std"], default-features = false }
+tabled = { path = "../tabled", features = ["std"], default-features = false }
 
 [dev-dependencies]
-tabled = { version = "0.11", features = ["std", "derive"], default-features = false }
+tabled = { path = "../tabled", features = ["std", "derive"], default-features = false }
diff --git a/tabled/Cargo.toml b/tabled/Cargo.toml
index 5bbce0c..bbbd806 100644
--- a/tabled/Cargo.toml
+++ b/tabled/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "tabled"
-version = "0.11.0-fix.docs.rs.2"
+version = "0.11.1"
 authors = ["Maxim Zhiburt <zhiburt@gmail.com>"]
 edition = "2018"
 description = "An easy to use library for pretty print tables of Rust `struct`s and `enum`s."
@@ -262,7 +262,7 @@ color = ["papergrid/color", "ansi-str", "ansitok", "std"]
 macros = ["std"]
 
 [dependencies]
-papergrid = { version = "0.8.2", default-features = false }
+papergrid = { path = "../papergrid", default-features = false }
 tabled_derive = { version = "0.6.0", optional = true }
 ansi-str = { version = "0.7.2", optional = true }
 ansitok = { version = "0.2.0", optional = true }
diff --git a/tabled/benches/lib_comp/README.md b/tabled/benches/lib_comp/README.md
index 4468208..9d2f28b 100644
--- a/tabled/benches/lib_comp/README.md
+++ b/tabled/benches/lib_comp/README.md
@@ -1,28 +1,28 @@
 # Benchmark's result
 
 
-|                          | cli_table      | comfy_table  | prettytable_rs    | term_table    | tabled           | tabled_color    | tabled_compact     | tabled_iter        |
-|--------------------------|----------------|--------------|-------------------|---------------|------------------|-----------------|--------------------|--------------------|
-| test_const_table/1       | 2.5±0.06µs     | 4.9±0.06µs   | 1326.4±24.28ns    | 4.7±0.06µs    | 1527.2±59.52ns   | 1518.3±14.38ns  | **1310.7±16.20ns** | 2.2±0.03µs         |
-| test_const_table/8       | 48.1±0.67µs    | 51.9±0.50µs  | **22.9±0.22µs**   | 101.2±1.59µs  | 23.6±0.50µs      | 23.7±0.58µs     | 23.8±0.42µs        | 37.6±0.35µs        |
-| test_const_table/32      | 695.8±4.16µs   | 764.6±4.17µs | 331.9±2.90µs      | 1200.9±7.36µs | **272.9±1.69µs** | 273.6±1.76µs    | 318.1±3.36µs       | 510.5±6.14µs       |
-| test_const_table/128     | 9.7±0.09ms     | 10.8±0.56ms  | 5.2±0.02ms        | 18.1±0.07ms   | 4.5±0.03ms       | **4.3±0.02ms**  | 4.6±0.02ms         | 7.2±0.27ms         |
-| test_const_table/512     | 171.3±1.38ms   | 179.8±0.96ms | 175.1±2.26ms      | 282.9±1.61ms  | 66.8±0.67ms      | **65.0±0.51ms** | 76.2±0.76ms        | 121.4±0.89ms       |
-| test_dynamic_table/1     | 2.2±0.03µs     | 5.0±0.04µs   | **825.4±12.90ns** | 2.7±0.02µs    | 1270.9±19.56ns   | 1272.8±18.33ns  | 921.5±14.97ns      | 1883.3±18.17ns     |
-| test_dynamic_table/8     | 39.6±0.64µs    | 52.3±0.51µs  | **15.9±0.24µs**   | 57.8±0.54µs   | 19.0±0.35µs      | 18.9±0.31µs     | 16.9±0.27µs        | 31.9±0.24µs        |
-| test_dynamic_table/32    | 543.1±3.08µs   | 651.4±5.91µs | **218.7±1.47µs**  | 873.1±6.74µs  | 239.6±5.23µs     | 252.3±1.49µs    | 256.4±8.01µs       | 430.0±1.92µs       |
-| test_dynamic_table/128   | 7.4±0.06ms     | 9.6±0.05ms   | 4.1±0.69ms        | 14.0±0.07ms   | 3.9±0.03ms       | **3.7±0.01ms**  | 4.1±0.01ms         | 7.2±0.08ms         |
-| test_dynamic_table/512   | 145.1±1.07ms   | 173.0±1.22ms | 155.4±2.51ms      | 258.6±2.32ms  | 60.0±0.50ms      | **58.9±0.56ms** | 66.4±1.78ms        | 111.8±4.54ms       |
-| test_empty_table/1       | 1571.9±16.67ns | 5.1±0.13µs   | **655.0±5.90ns**  | 2.2±0.01µs    | 998.7±61.50ns    | 1025.9±30.54ns  | 694.9±8.84ns       | 1252.4±5.66ns      |
-| test_empty_table/8       | 22.2±0.40µs    | 47.1±1.77µs  | **9.0±0.04µs**    | 46.2±1.45µs   | 10.8±0.08µs      | 10.6±0.20µs     | 9.9±0.58µs         | 11.1±0.07µs        |
-| test_empty_table/32      | 280.6±1.75µs   | 612.1±7.36µs | 121.3±1.34µs      | 632.1±2.94µs  | **118.4±0.50µs** | 121.2±0.55µs    | 126.6±8.45µs       | 120.8±1.52µs       |
-| test_empty_table/128     | 3.7±0.02ms     | 9.5±0.05ms   | 2.3±0.36ms        | 8.6±0.04ms    | 1697.3±12.78µs   | 1708.6±8.88µs   | 1798.5±4.14µs      | **1653.1±10.08µs** |
-| test_empty_table/512     | 67.7±1.04ms    | 161.6±1.13ms | 121.2±1.99ms      | 143.6±0.71ms  | 29.0±0.28ms      | 27.7±0.20ms     | 29.2±0.20ms        | **26.8±0.22ms**    |
-| test_multiline_table/1   | 8.2±0.21µs     | 11.5±0.08µs  | **2.6±0.02µs**    | 10.5±0.05µs   | 4.6±0.05µs       | 4.8±0.04µs      | *2.2±0.02µs*       | 8.4±0.03µs         |
-| test_multiline_table/8   | 157.0±1.71µs   | 218.7±1.01µs | **63.2±0.42µs**   | 307.3±10.20µs | 120.7±1.07µs     | 120.3±1.19µs    | *52.5±0.40µs*      | 216.6±1.91µs       |
-| test_multiline_table/32  | 2.0±0.01ms     | 2.9±0.02ms   | **848.1±4.60µs**  | 4.3±0.42ms    | 1555.6±14.21µs   | 1555.3±48.26µs  | *729.2±16.41µs*    | 3.3±0.06ms         |
-| test_multiline_table/128 | 30.6±0.39ms    | 44.0±0.44ms  | **13.0±0.10ms**   | 63.6±0.30ms   | 23.1±0.12ms      | 23.1±0.19ms     | *11.1±0.23ms*      | 47.3±0.18ms        |
-| test_multiline_table/512 | 530.3±2.26ms   | 747.4±3.02ms | **312.2±2.49ms**  | 1028.6±3.51ms | 393.1±2.53ms     | 400.8±1.76ms    | *181.2±2.83ms*     | 797.4±3.43ms       |
+|                          | cli_table      | comfy_table   | prettytable_rs     | term_table     | tabled           | tabled_color   | tabled_compact     | tabled_iter    |
+|--------------------------|----------------|---------------|--------------------|----------------|------------------|----------------|--------------------|----------------|
+| test_const_table/1       | 2.5±0.02µs     | 5.0±0.07µs    | **1324.7±17.84ns** | 4.6±0.03µs     | 1642.2±33.51ns   | 1639.9±32.57ns | 1385.8±18.37ns     | 2.5±0.07µs     |
+| test_const_table/8       | 49.7±0.74µs    | 54.8±0.42µs   | **23.4±0.69µs**    | 93.8±1.02µs    | 25.4±0.36µs      | 25.3±0.42µs    | 25.2±0.38µs        | 39.2±0.29µs    |
+| test_const_table/32      | 664.5±3.82µs   | 698.6±3.41µs  | 335.8±1.45µs       | 1289.8±6.95µs  | **295.2±3.00µs** | 333.1±3.08µs   | 317.1±3.22µs       | 541.6±2.82µs   |
+| test_const_table/128     | 9.4±0.12ms     | 11.5±0.08ms   | 5.3±0.03ms         | 17.6±0.35ms    | **4.5±0.02ms**   | 5.0±0.04ms     | **4.5±0.55ms**     | 7.5±0.05ms     |
+| test_const_table/512     | 172.5±1.00ms   | 172.0±0.94ms  | 185.0±2.12ms       | 273.0±1.34ms   | 78.2±0.36ms      | 70.7±0.47ms    | **70.2±0.49ms**    | 120.5±0.75ms   |
+| test_dynamic_table/1     | 2.2±0.07µs     | 5.4±0.07µs    | **858.6±15.43ns**  | 2.8±0.03µs     | 1420.5±22.66ns   | 1416.0±21.75ns | 1040.5±20.86ns     | 2.2±0.01µs     |
+| test_dynamic_table/8     | 42.5±0.65µs    | 47.5±0.28µs   | **15.8±0.26µs**    | 63.9±0.46µs    | 20.7±0.38µs      | 19.2±0.28µs    | 17.5±0.27µs        | 34.7±0.84µs    |
+| test_dynamic_table/32    | 538.1±9.81µs   | 703.3±3.28µs  | **225.9±2.63µs**   | 863.3±8.25µs   | 255.7±2.93µs     | 251.2±3.25µs   | 256.8±1.91µs       | 448.9±3.19µs   |
+| test_dynamic_table/128   | 8.3±0.04ms     | 10.6±0.05ms   | **3.8±0.06ms**     | 14.1±0.10ms    | 4.0±0.33ms       | 3.9±0.02ms     | 4.0±0.01ms         | 7.1±0.03ms     |
+| test_dynamic_table/512   | 140.0±0.80ms   | 160.2±0.86ms  | 149.6±2.07ms       | 245.4±1.04ms   | **62.2±0.35ms**  | 64.3±5.28ms    | 71.9±0.58ms        | 115.4±0.80ms   |
+| test_empty_table/1       | 1579.2±13.03ns | 4.6±0.03µs    | **628.4±5.51ns**   | 2.0±0.01µs     | 1140.6±33.58ns   | 1126.3±15.39ns | 731.9±6.03ns       | 1591.7±14.58ns |
+| test_empty_table/8       | 23.9±0.33µs    | 44.8±0.23µs   | **8.6±0.06µs**     | 50.0±0.36µs    | 11.2±0.05µs      | 11.3±0.08µs    | 9.4±0.05µs         | 12.6±0.10µs    |
+| test_empty_table/32      | 264.5±11.17µs  | 598.1±2.98µs  | **121.7±0.74µs**   | 572.3±6.17µs   | 133.7±0.96µs     | 146.5±0.40µs   | 131.2±0.54µs       | 143.1±0.62µs   |
+| test_empty_table/128     | 3.7±0.03ms     | 10.0±0.05ms   | 2.1±0.01ms         | 9.0±0.11ms     | 1963.3±7.43µs    | 1968.8±10.20µs | **1828.5±20.84µs** | 2.1±0.01ms     |
+| test_empty_table/512     | 67.5±0.69ms    | 162.3±1.11ms  | 126.8±1.82ms       | 141.6±1.00ms   | 31.5±1.09ms      | 31.5±0.24ms    | **28.7±0.18ms**    | 35.8±0.18ms    |
+| test_multiline_table/1   | 7.6±0.21µs     | 11.4±0.09µs   | **2.6±0.04µs**     | 10.5±0.06µs    | 5.2±0.03µs       | 5.6±0.04µs     | *2.2±0.02µs*       | 9.9±0.07µs     |
+| test_multiline_table/8   | 157.4±1.81µs   | 213.1±1.42µs  | **60.9±0.37µs**    | 327.3±1.90µs   | 118.7±0.50µs     | 118.6±0.42µs   | *54.9±0.35µs*      | 252.7±1.17µs   |
+| test_multiline_table/32  | 2.1±0.01ms     | 2.8±0.02ms    | **823.3±6.33µs**   | 4.3±0.04ms     | 1688.3±8.37µs    | 1627.1±6.26µs  | *793.8±10.24µs*    | 3.5±0.04ms     |
+| test_multiline_table/128 | 34.8±0.37ms    | 46.8±0.26ms   | **12.9±0.07ms**    | 71.1±0.33ms    | 25.0±0.13ms      | 25.6±0.19ms    | *11.3±0.09ms*      | 48.2±0.25ms    |
+| test_multiline_table/512 | 583.7±3.61ms   | 741.4±21.18ms | **337.1±1.86ms**   | 1022.6±13.76ms | 408.9±10.96ms    | 406.9±27.88ms  | *177.5±1.04ms*     | 759.4±5.55ms   |
 
 * tabled_compact doesn't support multiline strings
 
diff --git a/tabled/benches/lib_comp/src/lib.rs b/tabled/benches/lib_comp/src/lib.rs
index f43e107..2f87e08 100644
--- a/tabled/benches/lib_comp/src/lib.rs
+++ b/tabled/benches/lib_comp/src/lib.rs
@@ -30,10 +30,9 @@ pub mod tabled_current {
 
     #[inline]
     pub fn build(columns: Vec<String>, data: Vec<Vec<String>>) -> String {
-        Builder::from_iter(data)
-            .set_header(columns)
-            .build()
-            .to_string()
+        let mut b = Builder::from_iter(data);
+        b.set_header(columns);
+        b.build().to_string()
     }
 }
 
@@ -43,10 +42,9 @@ pub mod tabled_color_current {
 
     #[inline]
     pub fn build(columns: Vec<String>, data: Vec<Vec<String>>) -> String {
-        Builder::from_iter(data)
-            .set_header(columns)
-            .build()
-            .to_string()
+        let mut b = Builder::from_iter(data);
+        b.set_header(columns);
+        b.build().to_string()
     }
 }
 
diff --git a/tabled/examples/colored_padding.rs b/tabled/examples/colored_padding.rs
index ac44a8b..96a3a71 100644
--- a/tabled/examples/colored_padding.rs
+++ b/tabled/examples/colored_padding.rs
@@ -138,13 +138,14 @@ fn main() {
     println!("\n\n{table}\n\n");
 }
 
+#[derive(Debug, Clone)]
 struct MakeMaxPadding;
 
 impl<T> CellOption<VecRecords<T>, ColoredConfig> for MakeMaxPadding
 where
     T: Cell + AsRef<str>,
 {
-    fn change(&mut self, records: &mut VecRecords<T>, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut VecRecords<T>, cfg: &mut ColoredConfig, entity: Entity) {
         let widths = SpannedGridDimension::width(&*records, cfg);
 
         let count_rows = records.count_rows();
diff --git a/tabled/examples/terminal_size/src/main.rs b/tabled/examples/terminal_size/src/main.rs
index f13f4d9..664bffd 100644
--- a/tabled/examples/terminal_size/src/main.rs
+++ b/tabled/examples/terminal_size/src/main.rs
@@ -1,7 +1,7 @@
 //! The example shows how we could spread a table to the size of a terminal.
 
 use tabled::{
-    settings::{Height, Style, Width},
+    settings::{Height, Settings, Style, Width},
     Table, Tabled,
 };
 
@@ -45,15 +45,17 @@ fn main() {
     table.with(Style::extended());
 
     if use_width {
-        table
-            .with(Width::wrap(width as usize))
-            .with(Width::increase(width as usize));
+        table.with(Settings::new(
+            Width::wrap(width as usize),
+            Width::increase(width as usize),
+        ));
     }
 
     if use_height {
-        table
-            .with(Height::increase(height as usize))
-            .with(Height::limit(height as usize));
+        table.with(Settings::new(
+            Height::increase(height as usize),
+            Height::limit(height as usize),
+        ));
     }
 
     println!("{table}");
diff --git a/tabled/src/grid/colored_config.rs b/tabled/src/grid/colored_config.rs
index a07a5a1..51a00fb 100644
--- a/tabled/src/grid/colored_config.rs
+++ b/tabled/src/grid/colored_config.rs
@@ -1,22 +1,24 @@
-use std::collections::HashMap;
 use std::ops::{Deref, DerefMut};
 
-use papergrid::{
+use crate::grid::{
     color::AnsiColor,
-    config::{spanned::SpannedConfig, Position},
+    config::{Entity, EntityMap, SpannedConfig},
 };
 
 /// A spanned configuration plus colors for cells.
 #[derive(Debug, Default, PartialEq, Eq, Clone)]
 pub struct ColoredConfig {
     config: SpannedConfig,
-    colors: HashMap<Position, AnsiColor<'static>>,
+    colors: ColorMap,
 }
 
 impl ColoredConfig {
     /// Create a new colored config.
-    pub fn new(config: SpannedConfig, colors: HashMap<Position, AnsiColor<'static>>) -> Self {
-        Self { config, colors }
+    pub fn new(config: SpannedConfig) -> Self {
+        Self {
+            config,
+            colors: ColorMap::default(),
+        }
     }
 
     /// Set a color for a given cell.
@@ -25,15 +27,43 @@ impl ColoredConfig {
     /// While this method works in all contexts.
     ///
     /// [`Format`]: crate::settings::Format
-    pub fn set_color(&mut self, pos: Position, color: AnsiColor<'static>) -> &mut Self {
-        let _ = self.colors.insert(pos, color);
+    pub fn set_color(&mut self, pos: Entity, color: AnsiColor<'static>) -> &mut Self {
+        match self.colors.0.as_mut() {
+            Some(map) => map.insert(pos, color),
+            None => {
+                let mut colors = EntityMap::default();
+                colors.insert(pos, color);
+                self.colors = ColorMap(Some(colors));
+            }
+        }
+
+        self
+    }
+
+    /// Set a list of colors.
+    pub fn set_colors(&mut self, colors: EntityMap<AnsiColor<'static>>) -> &mut Self {
+        self.colors = ColorMap(Some(colors));
+        self
+    }
+
+    /// Remove a color for a given cell.
+    pub fn remove_color(&mut self, pos: Entity) -> &mut Self {
+        if let Some(colors) = self.colors.0.as_mut() {
+            colors.remove(pos);
+        }
+
         self
     }
 
     /// Returns a list of colors.
-    pub fn get_colors(&self) -> &HashMap<Position, AnsiColor<'static>> {
+    pub fn get_colors(&self) -> &ColorMap {
         &self.colors
     }
+
+    /// Returns an inner config.
+    pub fn into_inner(self) -> SpannedConfig {
+        self.config
+    }
 }
 
 impl Deref for ColoredConfig {
@@ -52,7 +82,7 @@ impl DerefMut for ColoredConfig {
 
 impl From<SpannedConfig> for ColoredConfig {
     fn from(value: SpannedConfig) -> Self {
-        Self::new(value, Default::default())
+        Self::new(value)
     }
 }
 
@@ -61,3 +91,22 @@ impl AsRef<SpannedConfig> for ColoredConfig {
         &self.config
     }
 }
+
+/// A colors structure for [`ColoredConfig`].
+#[derive(Debug, Default, PartialEq, Eq, Clone)]
+pub struct ColorMap(Option<EntityMap<AnsiColor<'static>>>);
+
+impl ColorMap {
+    /// Checks if any colors is set on.
+    pub fn is_empty(&self) -> bool {
+        self.0.is_none()
+    }
+}
+
+impl crate::grid::colors::Colors for ColorMap {
+    type Color = AnsiColor<'static>;
+
+    fn get_color(&self, (row, col): (usize, usize)) -> Option<&Self::Color> {
+        self.0.as_ref().map(|map| map.get(Entity::Cell(row, col)))
+    }
+}
diff --git a/tabled/src/grid/compact_multiline_config.rs b/tabled/src/grid/compact_multiline_config.rs
index 4c7ff3e..c9056c9 100644
--- a/tabled/src/grid/compact_multiline_config.rs
+++ b/tabled/src/grid/compact_multiline_config.rs
@@ -8,6 +8,7 @@ use crate::grid::config::{
 pub struct CompactMultilineConfig {
     config: CompactConfig,
     alignment_vertical: AlignmentVertical,
+    formatting: Formatting,
 }
 
 impl CompactMultilineConfig {
@@ -108,16 +109,27 @@ impl CompactMultilineConfig {
         self.config.get_margin_color()
     }
 
-    /// Set a padding to a given cells.
+    /// Set a padding color to all cells.
     pub const fn set_padding_color(mut self, color: Sides<StaticColor>) -> Self {
         self.config = self.config.set_padding_color(color);
         self
     }
 
-    /// Set a padding to a given cells.
+    /// get a padding color.
     pub const fn get_padding_color(&self) -> Sides<StaticColor> {
         self.config.get_padding_color()
     }
+
+    /// Set formatting.
+    pub const fn set_formatting(mut self, formatting: Formatting) -> Self {
+        self.formatting = formatting;
+        self
+    }
+
+    /// Get formatting.
+    pub const fn get_formatting(&self) -> Formatting {
+        self.formatting
+    }
 }
 
 impl Default for CompactMultilineConfig {
@@ -125,6 +137,7 @@ impl Default for CompactMultilineConfig {
         Self {
             config: Default::default(),
             alignment_vertical: AlignmentVertical::Top,
+            formatting: Formatting::default(),
         }
     }
 }
@@ -134,6 +147,7 @@ impl From<CompactConfig> for CompactMultilineConfig {
         Self {
             config,
             alignment_vertical: AlignmentVertical::Top,
+            formatting: Formatting::default(),
         }
     }
 }
@@ -157,6 +171,41 @@ impl From<CompactMultilineConfig> for crate::grid::config::SpannedConfig {
 
         let mut cfg = crate::grid::config::SpannedConfig::from(compact.config);
         cfg.set_alignment_vertical(Entity::Global, compact.alignment_vertical);
+        cfg.set_formatting(Entity::Global, compact.formatting.into());
+
         cfg
     }
 }
+
+/// Formatting represent a logic of formatting of a cell.
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Formatting {
+    /// An setting to allow horizontal trim.
+    pub horizontal_trim: bool,
+    /// An setting to allow vertical trim.
+    pub vertical_trim: bool,
+    /// An setting to allow alignment per line.
+    pub allow_lines_alignment: bool,
+}
+
+impl Formatting {
+    /// Creates a new [`Formatting`] structure.
+    pub fn new(horizontal_trim: bool, vertical_trim: bool, allow_lines_alignment: bool) -> Self {
+        Self {
+            horizontal_trim,
+            vertical_trim,
+            allow_lines_alignment,
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+impl From<Formatting> for crate::grid::config::Formatting {
+    fn from(val: Formatting) -> Self {
+        crate::grid::config::Formatting {
+            allow_lines_alignment: val.allow_lines_alignment,
+            horizontal_trim: val.horizontal_trim,
+            vertical_trim: val.vertical_trim,
+        }
+    }
+}
diff --git a/tabled/src/grid/dimension/complete_dimension_vec_records.rs b/tabled/src/grid/dimension/complete_dimension_vec_records.rs
new file mode 100644
index 0000000..ddc806a
--- /dev/null
+++ b/tabled/src/grid/dimension/complete_dimension_vec_records.rs
@@ -0,0 +1,128 @@
+use std::borrow::Cow;
+
+use papergrid::{
+    dimension::spanned_vec_records::SpannedVecRecordsDimension, records::vec_records::VecRecords,
+};
+
+use crate::grid::{
+    config::{ColoredConfig, SpannedConfig},
+    dimension::{Dimension, Estimate},
+    records::vec_records::Cell,
+};
+
+/// CompleteDimension is a [`Dimension`] implementation for a [`Table`]
+///
+/// [`Table`]: crate::Table
+#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone)]
+pub struct CompleteDimensionVecRecords<'a> {
+    width: Option<Cow<'a, [usize]>>,
+    height: Option<Cow<'a, [usize]>>,
+}
+
+impl CompleteDimensionVecRecords<'_> {
+    /// Checks whether is the dimensions is set.
+    pub fn is_complete(&self) -> bool {
+        self.width.is_some() && self.height.is_some()
+    }
+
+    /// Checks whether is nothing was set.
+    pub fn is_empty(&self) -> bool {
+        self.width.is_none() && self.height.is_none()
+    }
+
+    /// Set column widths.
+    ///
+    /// In general the method is only considered to be useful to a [`TableOption`].
+    ///
+    /// BE CAREFUL WITH THIS METHOD as it supposed that the content is not bigger than the provided widths.
+    ///
+    /// [`TableOption`]: crate::settings::TableOption
+    pub fn set_widths(&mut self, columns: Vec<usize>) -> bool {
+        self.width = Some(Cow::Owned(columns));
+
+        true
+    }
+
+    /// Set rows heights.
+    ///
+    /// In general the method is only considered to be useful to a [`TableOption`].
+    ///
+    /// BE CAREFUL WITH THIS METHOD as it supposed that the content is not bigger than the provided heights.
+    ///
+    /// [`TableOption`]: crate::settings::TableOption
+    pub fn set_heights(&mut self, rows: Vec<usize>) -> bool {
+        self.height = Some(Cow::Owned(rows));
+
+        true
+    }
+
+    /// Force width estimation.
+    pub fn clear_width(&mut self) {
+        self.width = None;
+    }
+
+    /// Force height estimation.
+    pub fn clear_height(&mut self) {
+        self.height = None;
+    }
+
+    /// Copies a reference from self.
+    pub fn from_origin(&self) -> CompleteDimensionVecRecords<'_> {
+        let width = self.width.as_deref().map(Cow::Borrowed);
+        let height = self.height.as_deref().map(Cow::Borrowed);
+
+        CompleteDimensionVecRecords { width, height }
+    }
+}
+
+impl Dimension for CompleteDimensionVecRecords<'_> {
+    fn get_width(&self, column: usize) -> usize {
+        let width = self
+            .width
+            .as_ref()
+            .expect("It must always be Some at this point");
+
+        width[column]
+    }
+
+    fn get_height(&self, row: usize) -> usize {
+        let height = self
+            .height
+            .as_ref()
+            .expect("It must always be Some at this point");
+
+        height[row]
+    }
+}
+
+impl<T: AsRef<str> + Cell> Estimate<&VecRecords<T>, SpannedConfig>
+    for CompleteDimensionVecRecords<'_>
+{
+    fn estimate(&mut self, records: &VecRecords<T>, cfg: &SpannedConfig) {
+        match (self.width.is_some(), self.height.is_some()) {
+            (true, true) => {}
+            (true, false) => {
+                self.height = Some(Cow::Owned(SpannedVecRecordsDimension::height(records, cfg)));
+            }
+            (false, true) => {
+                self.width = Some(Cow::Owned(SpannedVecRecordsDimension::width(records, cfg)));
+            }
+            (false, false) => {
+                let mut dims = SpannedVecRecordsDimension::default();
+                dims.estimate(records, cfg);
+
+                let (width, height) = dims.get_values();
+                self.width = Some(Cow::Owned(width));
+                self.height = Some(Cow::Owned(height));
+            }
+        }
+    }
+}
+
+impl<T: AsRef<str> + Cell> Estimate<&VecRecords<T>, ColoredConfig>
+    for CompleteDimensionVecRecords<'_>
+{
+    fn estimate(&mut self, records: &VecRecords<T>, cfg: &ColoredConfig) {
+        self.estimate(records, cfg.as_ref())
+    }
+}
diff --git a/tabled/src/grid/dimension/mod.rs b/tabled/src/grid/dimension/mod.rs
index 2192c3e..2f67b40 100644
--- a/tabled/src/grid/dimension/mod.rs
+++ b/tabled/src/grid/dimension/mod.rs
@@ -6,6 +6,8 @@ mod pool_table_dimension;
 #[cfg(feature = "std")]
 mod complete_dimension;
 #[cfg(feature = "std")]
+mod complete_dimension_vec_records;
+#[cfg(feature = "std")]
 mod peekable_dimension;
 #[cfg(feature = "std")]
 mod static_dimension;
@@ -14,6 +16,7 @@ mod static_dimension;
 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
 pub use self::{
     complete_dimension::CompleteDimension,
+    complete_dimension_vec_records::CompleteDimensionVecRecords,
     peekable_dimension::PeekableDimension,
     static_dimension::{DimensionValue, StaticDimension},
 };
@@ -23,7 +26,7 @@ pub use pool_table_dimension::{DimensionPriority, PoolTableDimension};
 
 #[cfg(feature = "std")]
 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
-pub use papergrid::dimension::compact::CompactGridDimension;
-#[cfg(feature = "std")]
-#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
-pub use papergrid::dimension::spanned::SpannedGridDimension;
+pub use papergrid::dimension::{
+    compact::CompactGridDimension, spanned::SpannedGridDimension,
+    spanned_vec_records::SpannedVecRecordsDimension,
+};
diff --git a/tabled/src/grid/mod.rs b/tabled/src/grid/mod.rs
index 3f24c36..cdd8c55 100644
--- a/tabled/src/grid/mod.rs
+++ b/tabled/src/grid/mod.rs
@@ -27,12 +27,12 @@ pub mod config {
     #[cfg(feature = "std")]
     #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
     pub use papergrid::config::spanned::{
-        Formatting, HorizontalLine, Offset, SpannedConfig, VerticalLine,
+        EntityMap, Formatting, HorizontalLine, Offset, SpannedConfig, VerticalLine,
     };
 
     #[cfg(feature = "std")]
     #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
-    pub use super::colored_config::ColoredConfig;
+    pub use super::colored_config::{ColorMap, ColoredConfig};
 
     pub use super::compact_multiline_config::CompactMultilineConfig;
 }
diff --git a/tabled/src/settings/alignment/mod.rs b/tabled/src/settings/alignment/mod.rs
index 4c9e233..e6d92d1 100644
--- a/tabled/src/settings/alignment/mod.rs
+++ b/tabled/src/settings/alignment/mod.rs
@@ -150,7 +150,7 @@ impl Alignment {
 
 #[cfg(feature = "std")]
 impl<R> crate::settings::CellOption<R, ColoredConfig> for Alignment {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         match self.inner {
             Horizontal(a) => cfg.set_alignment_horizontal(entity, a),
             Vertical(a) => cfg.set_alignment_vertical(entity, a),
@@ -160,7 +160,7 @@ impl<R> crate::settings::CellOption<R, ColoredConfig> for Alignment {
 
 #[cfg(feature = "std")]
 impl<R, D> TableOption<R, D, ColoredConfig> for Alignment {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         match self.inner {
             Horizontal(a) => cfg.set_alignment_horizontal(Entity::Global, a),
             Vertical(a) => cfg.set_alignment_vertical(Entity::Global, a),
@@ -169,7 +169,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for Alignment {
 }
 
 impl<R, D> TableOption<R, D, CompactConfig> for Alignment {
-    fn change(&mut self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         if let Horizontal(a) = self.inner {
             *cfg = cfg.set_alignment_horizontal(a)
         }
@@ -177,7 +177,7 @@ impl<R, D> TableOption<R, D, CompactConfig> for Alignment {
 }
 
 impl<R, D> TableOption<R, D, CompactMultilineConfig> for Alignment {
-    fn change(&mut self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
         match self.inner {
             Horizontal(a) => *cfg = cfg.set_alignment_horizontal(a),
             Vertical(a) => *cfg = cfg.set_alignment_vertical(a),
diff --git a/tabled/src/settings/cell_option.rs b/tabled/src/settings/cell_option.rs
index e4392c1..f589ac4 100644
--- a/tabled/src/settings/cell_option.rs
+++ b/tabled/src/settings/cell_option.rs
@@ -12,24 +12,25 @@ use crate::grid::{
 /// [`Cell`]: crate::object::Cell
 pub trait CellOption<R, C> {
     /// Modification function of a single cell.
-    fn change(&mut self, records: &mut R, cfg: &mut C, entity: Entity);
+    fn change(self, records: &mut R, cfg: &mut C, entity: Entity);
 }
 
-impl<T, R, C> CellOption<R, C> for &mut T
+#[cfg(feature = "std")]
+impl<R, C> CellOption<R, C> for String
 where
-    T: CellOption<R, C> + ?Sized,
+    R: Records + ExactRecords + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut C, entity: Entity) {
-        T::change(self, records, cfg, entity);
+    fn change(self, records: &mut R, cfg: &mut C, entity: Entity) {
+        (&self).change(records, cfg, entity);
     }
 }
 
 #[cfg(feature = "std")]
-impl<R, C> CellOption<R, C> for String
+impl<R, C> CellOption<R, C> for &String
 where
     R: Records + ExactRecords + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, entity: Entity) {
+    fn change(self, records: &mut R, _: &mut C, entity: Entity) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
@@ -43,7 +44,7 @@ impl<'a, R, C> CellOption<R, C> for &'a str
 where
     R: Records + ExactRecords + RecordsMut<&'a str>,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, entity: Entity) {
+    fn change(self, records: &mut R, _: &mut C, entity: Entity) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/color/mod.rs b/tabled/src/settings/color/mod.rs
index de4a35d..03ec591 100644
--- a/tabled/src/settings/color/mod.rs
+++ b/tabled/src/settings/color/mod.rs
@@ -8,7 +8,10 @@ use std::borrow::Cow;
 use crate::{
     grid::config::ColoredConfig,
     grid::records::{ExactRecords, Records, RecordsMut},
-    grid::{color::AnsiColor, config::Entity},
+    grid::{
+        color::{AnsiColor, StaticColor},
+        config::Entity,
+    },
     settings::{CellOption, TableOption},
 };
 
@@ -34,7 +37,7 @@ use crate::{
 /// [`Padding`]: crate::settings::Padding
 /// [`Margin`]: crate::settings::Margin
 /// [`Border`]: crate::settings::Border
-#[derive(Debug, Clone, Default, Eq, PartialEq)]
+#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Color(AnsiColor<'static>);
 
 // todo: Add | operation to combine colors
@@ -192,6 +195,15 @@ impl From<AnsiColor<'static>> for Color {
     }
 }
 
+impl From<StaticColor> for Color {
+    fn from(c: StaticColor) -> Self {
+        Self(AnsiColor::new(
+            Cow::Borrowed(c.get_prefix()),
+            Cow::Borrowed(c.get_suffix()),
+        ))
+    }
+}
+
 #[cfg(feature = "color")]
 impl std::convert::TryFrom<&str> for Color {
     type Error = ();
@@ -214,12 +226,8 @@ impl<R, D> TableOption<R, D, ColoredConfig> for Color
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        for row in 0..records.count_rows() {
-            for col in 0..records.count_columns() {
-                let _ = cfg.set_color((row, col), self.0.clone());
-            }
-        }
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        let _ = cfg.set_color(Entity::Global, self.0.clone());
     }
 }
 
@@ -227,14 +235,21 @@ impl<R> CellOption<R, ColoredConfig> for Color
 where
     R: Records + ExactRecords + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
-        for pos in entity.iter(records.count_rows(), records.count_columns()) {
-            let _ = cfg.set_color(pos, self.0.clone());
-        }
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+        let _ = cfg.set_color(entity, self.0.clone());
+    }
+}
+
+impl<R> CellOption<R, ColoredConfig> for &Color
+where
+    R: Records + ExactRecords + RecordsMut<String>,
+{
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+        let _ = cfg.set_color(entity, self.0.clone());
     }
 }
 
-impl papergrid::color::Color for Color {
+impl crate::grid::color::Color for Color {
     fn fmt_prefix<W: std::fmt::Write>(&self, f: &mut W) -> std::fmt::Result {
         self.0.fmt_prefix(f)
     }
diff --git a/tabled/src/settings/concat/mod.rs b/tabled/src/settings/concat/mod.rs
index 6af9994..b449a2e 100644
--- a/tabled/src/settings/concat/mod.rs
+++ b/tabled/src/settings/concat/mod.rs
@@ -115,7 +115,7 @@ impl<R, D, C> TableOption<R, D, C> for Concat
 where
     R: Records + ExactRecords + Resizable + PeekableRecords + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, _: &mut D) {
+    fn change(mut self, records: &mut R, _: &mut C, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
@@ -176,11 +176,11 @@ where
 #[derive(Debug, Default)]
 struct GetCell(String, Position);
 
-impl<R, D, C> TableOption<R, D, C> for GetCell
+impl<R, D, C> TableOption<R, D, C> for &mut GetCell
 where
     R: PeekableRecords,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, _: &mut D) {
+    fn change(self, records: &mut R, _: &mut C, _: &mut D) {
         let cell = records.get_text(self.1).to_string();
         self.0 = cell;
     }
diff --git a/tabled/src/settings/disable/mod.rs b/tabled/src/settings/disable/mod.rs
index 43ea52d..ba5bfac 100644
--- a/tabled/src/settings/disable/mod.rs
+++ b/tabled/src/settings/disable/mod.rs
@@ -154,7 +154,7 @@ where
     for<'a> L: Locator<&'a R, Coordinate = usize>,
     R: Records + Resizable,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, _: &mut D) {
+    fn change(mut self, records: &mut R, _: &mut C, _: &mut D) {
         let columns = self.locator.locate(records).into_iter().collect::<Vec<_>>();
 
         let mut shift = 0;
@@ -177,7 +177,7 @@ where
     for<'a> L: Locator<&'a R, Coordinate = usize>,
     R: ExactRecords + Resizable,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, _: &mut D) {
+    fn change(mut self, records: &mut R, _: &mut C, _: &mut D) {
         let rows = self.locator.locate(records).into_iter().collect::<Vec<_>>();
 
         let mut shift = 0;
diff --git a/tabled/src/settings/extract/mod.rs b/tabled/src/settings/extract/mod.rs
index c74286e..bba90a0 100644
--- a/tabled/src/settings/extract/mod.rs
+++ b/tabled/src/settings/extract/mod.rs
@@ -155,7 +155,7 @@ where
     C: RangeBounds<usize> + Clone,
     RR: Records + ExactRecords + Resizable,
 {
-    fn change(&mut self, records: &mut RR, _: &mut Cfg, _: &mut D) {
+    fn change(self, records: &mut RR, _: &mut Cfg, _: &mut D) {
         let count_rows = records.count_rows();
         let count_columns = records.count_columns();
 
diff --git a/tabled/src/settings/format/format_config.rs b/tabled/src/settings/format/format_config.rs
index 3a73a75..247ead3 100644
--- a/tabled/src/settings/format/format_config.rs
+++ b/tabled/src/settings/format/format_config.rs
@@ -2,13 +2,13 @@ use crate::settings::TableOption;
 
 /// This is a struct wrapper for a lambda which changes config.
 #[derive(Debug)]
-pub struct FormatConfig<F>(pub F);
+pub struct FormatConfig<F>(pub(crate) F);
 
 impl<F, R, D, C> TableOption<R, D, C> for FormatConfig<F>
 where
     F: FnMut(&mut C),
 {
-    fn change(&mut self, _: &mut R, cfg: &mut C, _: &mut D) {
+    fn change(mut self, _: &mut R, cfg: &mut C, _: &mut D) {
         (self.0)(cfg);
     }
 }
diff --git a/tabled/src/settings/format/format_content.rs b/tabled/src/settings/format/format_content.rs
index 8bc3f07..c14eee6 100644
--- a/tabled/src/settings/format/format_content.rs
+++ b/tabled/src/settings/format/format_content.rs
@@ -1,21 +1,26 @@
 use crate::{
     grid::config::Entity,
     grid::records::{ExactRecords, PeekableRecords, Records, RecordsMut},
-    settings::CellOption,
+    settings::{CellOption, TableOption},
 };
 
-use super::FormatContentPositioned;
-
 /// A lambda which formats cell content.
-#[derive(Debug)]
-pub struct FormatContent<F>(pub F)
-where
-    F: FnMut(&str) -> String;
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct FormatContent<F> {
+    f: F,
+    multiline: bool,
+}
 
-impl<F> FormatContent<F>
-where
-    F: FnMut(&str) -> String,
-{
+impl<F> FormatContent<F> {
+    pub(crate) fn new(f: F) -> Self {
+        Self {
+            f,
+            multiline: false,
+        }
+    }
+}
+
+impl<F> FormatContent<F> {
     /// Multiline a helper function for changing multiline content of cell.
     /// Using this formatting applied for all rows not to a string as a whole.
     ///
@@ -27,25 +32,49 @@ where
     ///     .with(Modify::new(Segment::all()).with(Format::content(|s| s.to_string()).multiline()))
     ///     .to_string();
     /// ```
-    pub fn multiline(self) -> FormatContent<impl FnMut(&str) -> String> {
-        FormatContent(multiline(self.0))
+    pub fn multiline(mut self) -> Self {
+        self.multiline = true;
+        self
     }
 }
 
-impl<F, R, C> CellOption<R, C> for FormatContent<F>
+impl<F, R, D, C> TableOption<R, D, C> for FormatContent<F>
 where
-    F: FnMut(&str) -> String,
+    F: FnMut(&str) -> String + Clone,
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut C, entity: Entity) {
-        FormatContentPositioned(|s, _| (self.0)(s)).change(records, cfg, entity);
+    fn change(self, records: &mut R, cfg: &mut C, _: &mut D) {
+        CellOption::change(self, records, cfg, Entity::Global);
     }
 }
 
-fn multiline<F>(mut f: F) -> impl FnMut(&str) -> String
+impl<F, R, C> CellOption<R, C> for FormatContent<F>
 where
-    F: FnMut(&str) -> String,
+    F: FnMut(&str) -> String + Clone,
+    R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
 {
+    fn change(mut self, records: &mut R, _: &mut C, entity: Entity) {
+        let count_rows = records.count_rows();
+        let count_cols = records.count_columns();
+
+        for pos in entity.iter(count_rows, count_cols) {
+            let is_valid_pos = pos.0 < count_rows && pos.1 < count_cols;
+            if !is_valid_pos {
+                continue;
+            }
+
+            let content = records.get_text(pos);
+            let content = if self.multiline {
+                multiline(self.f.clone())(content)
+            } else {
+                (self.f)(content)
+            };
+            records.set(pos, content);
+        }
+    }
+}
+
+fn multiline<F: FnMut(&str) -> String>(mut f: F) -> impl FnMut(&str) -> String {
     move |s: &str| {
         let mut v = Vec::new();
         for line in s.lines() {
diff --git a/tabled/src/settings/format/format_positioned.rs b/tabled/src/settings/format/format_positioned.rs
index cca05ea..e121f00 100644
--- a/tabled/src/settings/format/format_positioned.rs
+++ b/tabled/src/settings/format/format_positioned.rs
@@ -1,7 +1,7 @@
 use crate::{
     grid::config::Entity,
     grid::records::{ExactRecords, PeekableRecords, Records, RecordsMut},
-    settings::CellOption,
+    settings::{CellOption, TableOption},
 };
 
 /// [`FormatContentPositioned`] is like a [`FormatContent`] an abstraction over a function you can use against a cell.
@@ -9,17 +9,31 @@ use crate::{
 /// It different from [`FormatContent`] that it provides a row and column index.
 ///
 /// [`FormatContent`]: crate::settings::format::FormatContent
-#[derive(Debug)]
-pub struct FormatContentPositioned<F>(pub F)
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct FormatContentPositioned<F>(F);
+
+impl<F> FormatContentPositioned<F> {
+    pub(crate) fn new(f: F) -> Self {
+        Self(f)
+    }
+}
+
+impl<F, R, D, C> TableOption<R, D, C> for FormatContentPositioned<F>
 where
-    F: FnMut(&str, (usize, usize)) -> String;
+    F: FnMut(&str, (usize, usize)) -> String,
+    R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
+{
+    fn change(self, records: &mut R, cfg: &mut C, _: &mut D) {
+        CellOption::change(self, records, cfg, Entity::Global);
+    }
+}
 
 impl<F, R, C> CellOption<R, C> for FormatContentPositioned<F>
 where
     F: FnMut(&str, (usize, usize)) -> String,
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, entity: Entity) {
+    fn change(mut self, records: &mut R, _: &mut C, entity: Entity) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/format/mod.rs b/tabled/src/settings/format/mod.rs
index 1f621b0..adae98e 100644
--- a/tabled/src/settings/format/mod.rs
+++ b/tabled/src/settings/format/mod.rs
@@ -49,12 +49,11 @@ impl Format {
     ///                    +-------+-------------+-----------+");
     /// ```
     ///
-    pub fn content<F, S>(mut f: F) -> FormatContent<impl FnMut(&str) -> String>
+    pub fn content<F>(f: F) -> FormatContent<F>
     where
-        F: FnMut(&str) -> S,
-        S: Into<String>,
+        F: FnMut(&str) -> String,
     {
-        FormatContent(move |s: &str| (f)(s).into())
+        FormatContent::new(f)
     }
 
     /// This function creates a new [`FormatContentPositioned`], so
@@ -94,7 +93,7 @@ impl Format {
     where
         F: FnMut(&str, (usize, usize)) -> String,
     {
-        FormatContentPositioned(f)
+        FormatContentPositioned::new(f)
     }
 
     /// This function creates [`FormatConfig`] function to modify a table config.
diff --git a/tabled/src/settings/formatting/alignment_strategy.rs b/tabled/src/settings/formatting/alignment_strategy.rs
index fdd7738..c95facc 100644
--- a/tabled/src/settings/formatting/alignment_strategy.rs
+++ b/tabled/src/settings/formatting/alignment_strategy.rs
@@ -1,6 +1,6 @@
 use crate::{
-    grid::config::{ColoredConfig, Entity},
-    settings::CellOption,
+    grid::config::{ColoredConfig, CompactMultilineConfig, Entity},
+    settings::{CellOption, TableOption},
 };
 
 /// `AlignmentStrategy` is a responsible for a flow how we apply an alignment.
@@ -133,7 +133,7 @@ use crate::{
 /// │                                                             } │
 /// └───────────────────────────────────────────────────────────────┘"#);
 /// ```
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum AlignmentStrategy {
     /// Apply alignment for cell content as a whole.
     PerCell,
@@ -142,7 +142,7 @@ pub enum AlignmentStrategy {
 }
 
 impl<R> CellOption<R, ColoredConfig> for AlignmentStrategy {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let mut formatting = *cfg.get_formatting(entity);
         match &self {
             AlignmentStrategy::PerCell => formatting.allow_lines_alignment = false,
@@ -152,3 +152,21 @@ impl<R> CellOption<R, ColoredConfig> for AlignmentStrategy {
         cfg.set_formatting(entity, formatting);
     }
 }
+
+impl<R, D> TableOption<R, D, ColoredConfig> for AlignmentStrategy {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        <Self as CellOption<R, ColoredConfig>>::change(self, records, cfg, Entity::Global)
+    }
+}
+
+impl<R, D> TableOption<R, D, CompactMultilineConfig> for AlignmentStrategy {
+    fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
+        let mut f = cfg.get_formatting();
+        match &self {
+            AlignmentStrategy::PerCell => f.allow_lines_alignment = false,
+            AlignmentStrategy::PerLine => f.allow_lines_alignment = true,
+        }
+
+        *cfg = cfg.set_formatting(f);
+    }
+}
diff --git a/tabled/src/settings/formatting/charset.rs b/tabled/src/settings/formatting/charset.rs
index 3ac90ad..f6faa42 100644
--- a/tabled/src/settings/formatting/charset.rs
+++ b/tabled/src/settings/formatting/charset.rs
@@ -9,7 +9,7 @@ use crate::{
 };
 
 /// A structure to handle special chars.
-#[derive(Debug, Default, Clone)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Charset;
 
 impl Charset {
@@ -28,7 +28,7 @@ where
     for<'a> &'a R: Records,
     R: RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, _: &mut D) {
+    fn change(self, records: &mut R, _: &mut C, _: &mut D) {
         let mut list = vec![];
         for (row, cells) in records.iter_rows().into_iter().enumerate() {
             for (col, text) in cells.into_iter().enumerate() {
@@ -47,7 +47,7 @@ impl<R, C> CellOption<R, C> for CleanCharset
 where
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, entity: Entity) {
+    fn change(self, records: &mut R, _: &mut C, entity: Entity) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
         for pos in entity.iter(count_rows, count_cols) {
diff --git a/tabled/src/settings/formatting/tab_size.rs b/tabled/src/settings/formatting/tab_size.rs
index 2236a17..749e759 100644
--- a/tabled/src/settings/formatting/tab_size.rs
+++ b/tabled/src/settings/formatting/tab_size.rs
@@ -26,7 +26,7 @@ where
     for<'a> &'a R: Records,
     R: RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, _: &mut D) {
+    fn change(self, records: &mut R, _: &mut C, _: &mut D) {
         let mut list = vec![];
         for (row, cells) in records.iter_rows().into_iter().enumerate() {
             for (col, text) in cells.into_iter().enumerate() {
diff --git a/tabled/src/settings/formatting/trim_strategy.rs b/tabled/src/settings/formatting/trim_strategy.rs
index b242df0..64ec7e1 100644
--- a/tabled/src/settings/formatting/trim_strategy.rs
+++ b/tabled/src/settings/formatting/trim_strategy.rs
@@ -1,4 +1,8 @@
-use crate::{grid::config::ColoredConfig, grid::config::Entity, settings::CellOption};
+use crate::{
+    grid::config::ColoredConfig,
+    grid::config::Entity,
+    settings::{CellOption, TableOption},
+};
 
 /// `TrimStrategy` determines if it's allowed to use empty space while doing [`Alignment`].
 ///
@@ -69,7 +73,7 @@ use crate::{grid::config::ColoredConfig, grid::config::Entity, settings::CellOpt
 /// ```
 ///
 /// [`Alignment`]: crate::settings::Alignment
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum TrimStrategy {
     /// Allow vertical trim.
     Vertical,
@@ -82,7 +86,7 @@ pub enum TrimStrategy {
 }
 
 impl<R> CellOption<R, ColoredConfig> for TrimStrategy {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let mut formatting = *cfg.get_formatting(entity);
 
         // todo: could be changed to be a struct an enum like consts in `impl` block.
@@ -106,3 +110,9 @@ impl<R> CellOption<R, ColoredConfig> for TrimStrategy {
         cfg.set_formatting(entity, formatting);
     }
 }
+
+impl<R, D> TableOption<R, D, ColoredConfig> for TrimStrategy {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        <Self as CellOption<_, _>>::change(self, records, cfg, Entity::Global)
+    }
+}
diff --git a/tabled/src/settings/height/cell_height_increase.rs b/tabled/src/settings/height/cell_height_increase.rs
index 05c9e0f..39887f9 100644
--- a/tabled/src/settings/height/cell_height_increase.rs
+++ b/tabled/src/settings/height/cell_height_increase.rs
@@ -1,7 +1,7 @@
 use crate::{
     grid::config::ColoredConfig,
     grid::config::Entity,
-    grid::dimension::CompleteDimension,
+    grid::dimension::CompleteDimensionVecRecords,
     grid::records::{ExactRecords, PeekableRecords, Records, RecordsMut},
     grid::util::string::count_lines,
     settings::{measurement::Measurement, peaker::Peaker, CellOption, Height, TableOption},
@@ -15,7 +15,7 @@ use super::TableHeightIncrease;
 ///
 /// [`PriorityNone`]: crate::settings::peaker::PriorityNone
 /// [`Table`]: crate::Table
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct CellHeightIncrease<W = usize> {
     height: W,
 }
@@ -46,7 +46,7 @@ where
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
     for<'a> &'a R: Records,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let height = self.height.measure(&*records, cfg);
 
         let count_rows = records.count_rows();
@@ -71,17 +71,18 @@ where
     }
 }
 
-impl<R, W> TableOption<R, CompleteDimension<'static>, ColoredConfig> for CellHeightIncrease<W>
+impl<R, W> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig>
+    for CellHeightIncrease<W>
 where
     W: Measurement<Height>,
     R: Records + ExactRecords + PeekableRecords,
     for<'a> &'a R: Records,
 {
     fn change(
-        &mut self,
+        self,
         records: &mut R,
         cfg: &mut ColoredConfig,
-        dims: &mut CompleteDimension<'static>,
+        dims: &mut CompleteDimensionVecRecords<'static>,
     ) {
         let height = self.height.measure(&*records, cfg);
         TableHeightIncrease::new(height).change(records, cfg, dims)
diff --git a/tabled/src/settings/height/cell_height_limit.rs b/tabled/src/settings/height/cell_height_limit.rs
index 1c2f53c..788f030 100644
--- a/tabled/src/settings/height/cell_height_limit.rs
+++ b/tabled/src/settings/height/cell_height_limit.rs
@@ -1,7 +1,7 @@
 use crate::{
     grid::{
         config::{ColoredConfig, Entity},
-        dimension::CompleteDimension,
+        dimension::CompleteDimensionVecRecords,
         records::{ExactRecords, PeekableRecords, Records, RecordsMut},
         util::string::{count_lines, get_lines},
     },
@@ -16,7 +16,7 @@ use super::table_height_limit::TableHeightLimit;
 ///
 /// [`PriorityNone`]: crate::settings::peaker::PriorityNone
 /// [`Table`]: crate::Table
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct CellHeightLimit<W = usize> {
     height: W,
 }
@@ -46,7 +46,7 @@ where
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
     for<'a> &'a R: Records,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let height = self.height.measure(&*records, cfg);
 
         let count_rows = records.count_rows();
@@ -71,17 +71,18 @@ where
     }
 }
 
-impl<R, W> TableOption<R, CompleteDimension<'static>, ColoredConfig> for CellHeightLimit<W>
+impl<R, W> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig>
+    for CellHeightLimit<W>
 where
     W: Measurement<Height>,
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
     for<'a> &'a R: Records,
 {
     fn change(
-        &mut self,
+        self,
         records: &mut R,
         cfg: &mut ColoredConfig,
-        dims: &mut CompleteDimension<'static>,
+        dims: &mut CompleteDimensionVecRecords<'static>,
     ) {
         let height = self.height.measure(&*records, cfg);
         TableHeightLimit::new(height).change(records, cfg, dims)
diff --git a/tabled/src/settings/height/height_list.rs b/tabled/src/settings/height/height_list.rs
index c4bbe3c..7861dd4 100644
--- a/tabled/src/settings/height/height_list.rs
+++ b/tabled/src/settings/height/height_list.rs
@@ -1,7 +1,7 @@
 use std::iter::FromIterator;
 
 use crate::{
-    grid::dimension::CompleteDimension,
+    grid::dimension::CompleteDimensionVecRecords,
     grid::records::{ExactRecords, Records},
     settings::TableOption,
 };
@@ -33,15 +33,15 @@ impl FromIterator<usize> for HeightList {
     }
 }
 
-impl<R, C> TableOption<R, CompleteDimension<'static>, C> for HeightList
+impl<R, C> TableOption<R, CompleteDimensionVecRecords<'static>, C> for HeightList
 where
     R: ExactRecords + Records,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, dims: &mut CompleteDimension<'static>) {
+    fn change(self, records: &mut R, _: &mut C, dims: &mut CompleteDimensionVecRecords<'static>) {
         if self.list.len() < records.count_rows() {
             return;
         }
 
-        let _ = dims.set_heights(self.list.clone());
+        let _ = dims.set_heights(self.list);
     }
 }
diff --git a/tabled/src/settings/height/table_height_increase.rs b/tabled/src/settings/height/table_height_increase.rs
index 5eaa4dc..f727bf0 100644
--- a/tabled/src/settings/height/table_height_increase.rs
+++ b/tabled/src/settings/height/table_height_increase.rs
@@ -1,7 +1,9 @@
 use crate::{
-    grid::config::ColoredConfig,
-    grid::dimension::CompleteDimension,
-    grid::records::{ExactRecords, PeekableRecords, Records},
+    grid::{
+        config::ColoredConfig,
+        dimension::CompleteDimensionVecRecords,
+        records::{ExactRecords, PeekableRecords, Records},
+    },
     settings::{
         measurement::Measurement,
         peaker::{Peaker, PriorityNone},
@@ -42,7 +44,7 @@ impl<W> TableHeightIncrease<W, PriorityNone> {
     }
 }
 
-impl<R, W, P> TableOption<R, CompleteDimension<'static>, ColoredConfig>
+impl<R, W, P> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig>
     for TableHeightIncrease<W, P>
 where
     W: Measurement<Height>,
@@ -51,10 +53,10 @@ where
     for<'a> &'a R: Records,
 {
     fn change(
-        &mut self,
+        self,
         records: &mut R,
         cfg: &mut ColoredConfig,
-        dims: &mut CompleteDimension<'static>,
+        dims: &mut CompleteDimensionVecRecords<'static>,
     ) {
         if records.count_rows() == 0 || records.count_columns() == 0 {
             return;
@@ -66,7 +68,7 @@ where
             return;
         }
 
-        get_increase_list(&mut heights, height, total, self.priority.clone());
+        get_increase_list(&mut heights, height, total, self.priority);
 
         let _ = dims.set_heights(heights);
     }
diff --git a/tabled/src/settings/height/table_height_limit.rs b/tabled/src/settings/height/table_height_limit.rs
index 116811d..2a3d19b 100644
--- a/tabled/src/settings/height/table_height_limit.rs
+++ b/tabled/src/settings/height/table_height_limit.rs
@@ -1,8 +1,10 @@
 use crate::{
-    grid::config::ColoredConfig,
-    grid::dimension::CompleteDimension,
-    grid::records::{ExactRecords, PeekableRecords, Records, RecordsMut},
-    grid::util::string::{count_lines, get_lines},
+    grid::{
+        config::ColoredConfig,
+        dimension::CompleteDimensionVecRecords,
+        records::{ExactRecords, PeekableRecords, Records, RecordsMut},
+        util::string::{count_lines, get_lines},
+    },
     settings::{
         measurement::Measurement,
         peaker::{Peaker, PriorityNone},
@@ -43,7 +45,8 @@ impl<W> TableHeightLimit<W, PriorityNone> {
     }
 }
 
-impl<R, W, P> TableOption<R, CompleteDimension<'static>, ColoredConfig> for TableHeightLimit<W, P>
+impl<R, W, P> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig>
+    for TableHeightLimit<W, P>
 where
     W: Measurement<Height>,
     P: Peaker + Clone,
@@ -51,10 +54,10 @@ where
     for<'a> &'a R: Records,
 {
     fn change(
-        &mut self,
+        self,
         records: &mut R,
         cfg: &mut ColoredConfig,
-        dims: &mut CompleteDimension<'static>,
+        dims: &mut CompleteDimensionVecRecords<'static>,
     ) {
         let count_rows = records.count_rows();
         let count_cols = (&*records).count_columns();
@@ -69,7 +72,7 @@ where
             return;
         }
 
-        decrease_list(&mut heights, total, height, self.priority.clone());
+        decrease_list(&mut heights, total, height, self.priority);
 
         for (row, &height) in heights.iter().enumerate() {
             for col in 0..count_cols {
diff --git a/tabled/src/settings/highlight/mod.rs b/tabled/src/settings/highlight/mod.rs
index 7f37419..57df867 100644
--- a/tabled/src/settings/highlight/mod.rs
+++ b/tabled/src/settings/highlight/mod.rs
@@ -118,7 +118,7 @@ where
     O: Object<R>,
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
@@ -126,7 +126,7 @@ where
         let segments = split_segments(cells, count_rows, count_cols);
 
         for sector in segments {
-            set_border(cfg, &sector, self.border.clone());
+            set_border(cfg, &sector, self.border);
         }
     }
 }
@@ -145,7 +145,7 @@ where
     O: Object<R>,
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/margin/mod.rs b/tabled/src/settings/margin/mod.rs
index d97b0de..b86a1d3 100644
--- a/tabled/src/settings/margin/mod.rs
+++ b/tabled/src/settings/margin/mod.rs
@@ -95,7 +95,7 @@ impl<R, D, C> TableOption<R, D, ColoredConfig> for Margin<C>
 where
     C: Into<AnsiColor<'static>> + Clone,
 {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let indent = self.indent;
         let margin = Sides::new(indent.left, indent.right, indent.top, indent.bottom);
         cfg.set_margin(margin);
@@ -116,10 +116,10 @@ impl<R, D, C> TableOption<R, D, CompactConfig> for Margin<C>
 where
     C: Into<StaticColor> + Clone,
 {
-    fn change(&mut self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         *cfg = cfg.set_margin(self.indent);
 
-        if let Some(c) = self.colors.clone() {
+        if let Some(c) = self.colors {
             // todo: make a new method (BECAUSE INTO doesn't work) try_into();
             let colors = Sides::new(c.left.into(), c.right.into(), c.top.into(), c.bottom.into());
             *cfg = cfg.set_margin_color(colors);
@@ -131,7 +131,7 @@ impl<R, D, C> TableOption<R, D, CompactMultilineConfig> for Margin<C>
 where
     C: Into<StaticColor> + Clone,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
         self.change(records, cfg.as_mut(), dimension)
     }
 }
diff --git a/tabled/src/settings/merge/mod.rs b/tabled/src/settings/merge/mod.rs
index 6abbe8e..51fa2bb 100644
--- a/tabled/src/settings/merge/mod.rs
+++ b/tabled/src/settings/merge/mod.rs
@@ -38,7 +38,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for MergeDuplicatesVertical
 where
     R: Records + PeekableRecords + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
@@ -122,7 +122,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for MergeDuplicatesHorizontal
 where
     R: Records + PeekableRecords + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/modify.rs b/tabled/src/settings/modify.rs
index 83dc0f4..c712a25 100644
--- a/tabled/src/settings/modify.rs
+++ b/tabled/src/settings/modify.rs
@@ -8,7 +8,7 @@ use crate::{
 ///
 /// Be aware that the settings are applied all to a cell at a time.
 /// So sometimes you may need to make a several calls of [`Modify`] in order to achieve the desired affect.
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Modify<O> {
     obj: O,
 }
@@ -70,12 +70,12 @@ impl<O, M1> ModifyList<O, M1> {
 impl<O, M, R, D, C> TableOption<R, D, C> for ModifyList<O, M>
 where
     O: Object<R>,
-    M: CellOption<R, C>,
+    M: CellOption<R, C> + Clone,
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut C, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut C, _: &mut D) {
         for entity in self.obj.cells(records) {
-            self.modifiers.change(records, cfg, entity);
+            self.modifiers.clone().change(records, cfg, entity);
         }
     }
 }
diff --git a/tabled/src/settings/padding/mod.rs b/tabled/src/settings/padding/mod.rs
index 501092e..af343b3 100644
--- a/tabled/src/settings/padding/mod.rs
+++ b/tabled/src/settings/padding/mod.rs
@@ -57,7 +57,7 @@ use crate::settings::CellOption;
 /// # let data: Vec<&'static str> = Vec::new();
 /// let table = Table::new(&data).with(Modify::new(Rows::single(0)).with(Padding::new(0, 0, 1, 1).fill('>', '<', '^', 'V')));
 /// ```
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Padding<C = StaticColor> {
     indent: Sides<Indent>,
     colors: Option<Sides<C>>,
@@ -113,7 +113,7 @@ impl<R, C> CellOption<R, ColoredConfig> for Padding<C>
 where
     C: Into<AnsiColor<'static>> + Clone,
 {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let indent = self.indent;
         let pad = Sides::new(indent.left, indent.right, indent.top, indent.bottom);
         cfg.set_padding(entity, pad);
@@ -135,7 +135,7 @@ impl<R, D, C> TableOption<R, D, ColoredConfig> for Padding<C>
 where
     C: Into<AnsiColor<'static>> + Clone,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         <Self as CellOption<R, ColoredConfig>>::change(self, records, cfg, Entity::Global)
     }
 }
@@ -144,10 +144,10 @@ impl<R, D, C> TableOption<R, D, CompactConfig> for Padding<C>
 where
     C: Into<StaticColor> + Clone,
 {
-    fn change(&mut self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         *cfg = cfg.set_padding(self.indent);
 
-        if let Some(c) = self.colors.clone() {
+        if let Some(c) = self.colors {
             let colors = Sides::new(c.left.into(), c.right.into(), c.top.into(), c.bottom.into());
             *cfg = cfg.set_padding_color(colors);
         }
@@ -158,7 +158,7 @@ impl<R, D, C> TableOption<R, D, CompactMultilineConfig> for Padding<C>
 where
     C: Into<StaticColor> + Clone,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
         self.change(records, cfg.as_mut(), dimension)
     }
 }
diff --git a/tabled/src/settings/panel/footer.rs b/tabled/src/settings/panel/footer.rs
index c8f5dac..8d16481 100644
--- a/tabled/src/settings/panel/footer.rs
+++ b/tabled/src/settings/panel/footer.rs
@@ -26,7 +26,7 @@ where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
         Panel::horizontal(records.count_rows(), self.0.as_ref()).change(records, cfg, dimension);
     }
 }
diff --git a/tabled/src/settings/panel/header.rs b/tabled/src/settings/panel/header.rs
index a6340ab..e9d398c 100644
--- a/tabled/src/settings/panel/header.rs
+++ b/tabled/src/settings/panel/header.rs
@@ -26,7 +26,7 @@ where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
         Panel::horizontal(0, self.0.as_ref()).change(records, cfg, dimension);
     }
 }
diff --git a/tabled/src/settings/panel/horizontal_panel.rs b/tabled/src/settings/panel/horizontal_panel.rs
index 987c2dc..d5871d7 100644
--- a/tabled/src/settings/panel/horizontal_panel.rs
+++ b/tabled/src/settings/panel/horizontal_panel.rs
@@ -23,7 +23,7 @@ where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/panel/vertical_panel.rs b/tabled/src/settings/panel/vertical_panel.rs
index 73a3348..ddc0a56 100644
--- a/tabled/src/settings/panel/vertical_panel.rs
+++ b/tabled/src/settings/panel/vertical_panel.rs
@@ -26,7 +26,7 @@ where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/rotate/mod.rs b/tabled/src/settings/rotate/mod.rs
index ece14e2..4264171 100644
--- a/tabled/src/settings/rotate/mod.rs
+++ b/tabled/src/settings/rotate/mod.rs
@@ -67,7 +67,7 @@ impl<R, D, C> TableOption<R, D, C> for Rotate
 where
     R: Records + ExactRecords + Resizable,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, _: &mut D) {
+    fn change(self, records: &mut R, _: &mut C, _: &mut D) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/settings_list.rs b/tabled/src/settings/settings_list.rs
index 21fa2e8..dc8aec1 100644
--- a/tabled/src/settings/settings_list.rs
+++ b/tabled/src/settings/settings_list.rs
@@ -40,7 +40,7 @@ where
     A: CellOption<R, C>,
     B: CellOption<R, C>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut C, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut C, entity: Entity) {
         self.0.change(records, cfg, entity);
         self.1.change(records, cfg, entity);
     }
@@ -51,7 +51,7 @@ where
     A: TableOption<R, D, C>,
     B: TableOption<R, D, C>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut C, dims: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut C, dims: &mut D) {
         self.0.change(records, cfg, dims);
         self.1.change(records, cfg, dims);
     }
@@ -63,9 +63,9 @@ pub struct EmptySettings;
 
 #[cfg(feature = "std")]
 impl<R, C> CellOption<R, C> for EmptySettings {
-    fn change(&mut self, _: &mut R, _: &mut C, _: Entity) {}
+    fn change(self, _: &mut R, _: &mut C, _: Entity) {}
 }
 
 impl<R, D, C> TableOption<R, D, C> for EmptySettings {
-    fn change(&mut self, _: &mut R, _: &mut C, _: &mut D) {}
+    fn change(self, _: &mut R, _: &mut C, _: &mut D) {}
 }
diff --git a/tabled/src/settings/shadow/mod.rs b/tabled/src/settings/shadow/mod.rs
index 880a349..6b8ff48 100644
--- a/tabled/src/settings/shadow/mod.rs
+++ b/tabled/src/settings/shadow/mod.rs
@@ -38,7 +38,7 @@ use crate::{
 /// NOTICE: It uses [`Margin`] therefore it often can't be combined.
 ///
 /// [`Margin`]: crate::settings::Margin
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Shadow {
     c: char,
     size: usize,
@@ -66,54 +66,54 @@ impl Shadow {
     }
 
     /// The function, sets a characters for the [`Shadow`] to be used.
-    pub fn set_fill(&mut self, c: char) -> &mut Self {
+    pub fn set_fill(mut self, c: char) -> Self {
         self.c = c;
         self
     }
 
     /// Set an offset value (default is '1').
-    pub fn set_offset(&mut self, size: usize) -> &mut Self {
+    pub fn set_offset(mut self, size: usize) -> Self {
         self.size_offset = size;
         self
     }
 
     /// Switch shadow to top.
-    pub fn set_top(&mut self) -> &mut Self {
+    pub fn set_top(mut self) -> Self {
         self.direction.top = true;
         self.direction.bottom = false;
         self
     }
 
     /// Switch shadow to bottom.
-    pub fn set_bottom(&mut self) -> &mut Self {
+    pub fn set_bottom(mut self) -> Self {
         self.direction.bottom = true;
         self.direction.top = false;
         self
     }
 
     /// Switch shadow to left.
-    pub fn set_left(&mut self) -> &mut Self {
+    pub fn set_left(mut self) -> Self {
         self.direction.left = true;
         self.direction.right = false;
         self
     }
 
     /// Switch shadow to right.
-    pub fn set_right(&mut self) -> &mut Self {
+    pub fn set_right(mut self) -> Self {
         self.direction.right = true;
         self.direction.left = false;
         self
     }
 
     /// Sets a color for a shadow.
-    pub fn set_color(&mut self, color: Color) -> &mut Self {
+    pub fn set_color(mut self, color: Color) -> Self {
         self.color = Some(color);
         self
     }
 }
 
 impl<R, D> TableOption<R, D, ColoredConfig> for Shadow {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         set_margin(cfg, self.size, self.c, &self.direction);
         set_margin_offset(cfg, self.size_offset, &self.direction);
 
diff --git a/tabled/src/settings/span/column.rs b/tabled/src/settings/span/column.rs
index e34bed7..50af64c 100644
--- a/tabled/src/settings/span/column.rs
+++ b/tabled/src/settings/span/column.rs
@@ -7,7 +7,7 @@ use crate::{
 };
 
 /// Columns (Vertical) span.
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct ColumnSpan {
     size: usize,
 }
@@ -28,7 +28,7 @@ impl<R> CellOption<R, ColoredConfig> for ColumnSpan
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/span/row.rs b/tabled/src/settings/span/row.rs
index 02e17ce..68673f7 100644
--- a/tabled/src/settings/span/row.rs
+++ b/tabled/src/settings/span/row.rs
@@ -7,7 +7,7 @@ use crate::{
 };
 
 /// Row (vertical) span.
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct RowSpan {
     size: usize,
 }
@@ -28,7 +28,7 @@ impl<R> CellOption<R, ColoredConfig> for RowSpan
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let count_rows = records.count_rows();
         let count_cols = records.count_columns();
 
diff --git a/tabled/src/settings/split/mod.rs b/tabled/src/settings/split/mod.rs
index 31a5609..32f820a 100644
--- a/tabled/src/settings/split/mod.rs
+++ b/tabled/src/settings/split/mod.rs
@@ -236,14 +236,14 @@ impl<R, D, Cfg> TableOption<R, D, Cfg> for Split
 where
     R: Records + ExactRecords + Resizable + PeekableRecords,
 {
-    fn change(&mut self, records: &mut R, _: &mut Cfg, _: &mut D) {
+    fn change(self, records: &mut R, _: &mut Cfg, _: &mut D) {
         // variables
         let Split {
             direction,
             behavior,
             display,
             index: section_length,
-        } = *self;
+        } = self;
         let mut filtered_sections = 0;
 
         // early return check
diff --git a/tabled/src/settings/style/border.rs b/tabled/src/settings/style/border.rs
index 1293ba9..a8cbefb 100644
--- a/tabled/src/settings/style/border.rs
+++ b/tabled/src/settings/style/border.rs
@@ -29,7 +29,7 @@ use crate::{
 ///     .with(Style::ascii())
 ///     .with(Modify::new(Rows::single(0)).with(Border::default().top('x')));
 /// ```
-#[derive(Debug, Clone, Default, Eq, PartialEq)]
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Border(GBorder<char>);
 
 impl Border {
@@ -121,11 +121,11 @@ impl<R> CellOption<R, ColoredConfig> for Border
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let shape = (records.count_rows(), records.count_columns());
 
         for pos in entity.iter(shape.0, shape.1) {
-            cfg.set_border(pos, self.0.clone());
+            cfg.set_border(pos, self.0);
         }
     }
 }
@@ -142,14 +142,14 @@ impl From<Border> for GBorder<char> {
     }
 }
 
-#[derive(Debug)]
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct EmptyBorder;
 
 impl<R> CellOption<R, ColoredConfig> for EmptyBorder
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let shape = (records.count_rows(), records.count_columns());
 
         for pos in entity.iter(shape.0, shape.1) {
diff --git a/tabled/src/settings/style/border_char.rs b/tabled/src/settings/style/border_char.rs
index a809eed..b1e04c5 100644
--- a/tabled/src/settings/style/border_char.rs
+++ b/tabled/src/settings/style/border_char.rs
@@ -31,7 +31,7 @@ use super::Offset;
 ///     ),
 /// );
 /// ```
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct BorderChar {
     c: char,
     offset: Offset,
@@ -62,7 +62,7 @@ impl<R> CellOption<R, ColoredConfig> for BorderChar
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let cells = entity.iter(records.count_rows(), records.count_columns());
 
         match self.horizontal {
diff --git a/tabled/src/settings/style/border_color.rs b/tabled/src/settings/style/border_color.rs
index 5ca023d..6b3fa2b 100644
--- a/tabled/src/settings/style/border_color.rs
+++ b/tabled/src/settings/style/border_color.rs
@@ -118,7 +118,7 @@ impl<R> CellOption<R, ColoredConfig> for BorderColor
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let count_rows = records.count_rows();
         let count_columns = records.count_columns();
 
@@ -134,7 +134,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BorderColor
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let count_rows = records.count_rows();
         let count_columns = records.count_columns();
 
diff --git a/tabled/src/settings/style/border_text.rs b/tabled/src/settings/style/border_text.rs
index 0371cb0..163a198 100644
--- a/tabled/src/settings/style/border_text.rs
+++ b/tabled/src/settings/style/border_text.rs
@@ -95,7 +95,7 @@ where
     for<'a> D: Estimate<&'a R, ColoredConfig>,
     D: Dimension,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
         dims.estimate(records, cfg);
         let shape = (records.count_rows(), records.count_columns());
         let line = self.line;
@@ -110,7 +110,7 @@ where
     for<'a> D: Estimate<&'a R, ColoredConfig>,
     D: Dimension,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
         dims.estimate(records, cfg);
         let shape = (records.count_rows(), records.count_columns());
         let line = 0;
@@ -125,7 +125,7 @@ where
     for<'a> D: Estimate<&'a R, ColoredConfig>,
     D: Dimension,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
         dims.estimate(records, cfg);
         let shape = (records.count_rows(), records.count_columns());
         let line = records.count_rows();
diff --git a/tabled/src/settings/style/builder.rs b/tabled/src/settings/style/builder.rs
index 35d4ff0..d55c400 100644
--- a/tabled/src/settings/style/builder.rs
+++ b/tabled/src/settings/style/builder.rs
@@ -1050,16 +1050,16 @@ where
     HLines: IntoIterator<Item = HorizontalLine> + Clone,
     VLines: IntoIterator<Item = VerticalLine> + Clone,
 {
-    fn change(&mut self, records: &mut I, cfg: &mut ColoredConfig, dimension: &mut D) {
+    fn change(self, records: &mut I, cfg: &mut ColoredConfig, dimension: &mut D) {
         cfg.clear_theme();
 
         cfg.set_borders(self.borders);
 
-        for mut hl in self.horizontals.clone() {
+        for hl in self.horizontals {
             hl.change(records, cfg, dimension);
         }
 
-        for mut vl in self.verticals.clone() {
+        for vl in self.verticals {
             vl.change(records, cfg, dimension);
         }
     }
@@ -1070,11 +1070,11 @@ impl<T, B, L, R, H, V, HLines, VLines, I, D> TableOption<I, D, CompactConfig>
 where
     HLines: IntoIterator<Item = HorizontalLine> + Clone,
 {
-    fn change(&mut self, records: &mut I, cfg: &mut CompactConfig, dimension: &mut D) {
+    fn change(self, records: &mut I, cfg: &mut CompactConfig, dimension: &mut D) {
         *cfg = cfg.set_borders(self.borders);
 
-        let first_line = self.horizontals.clone().into_iter().next();
-        if let Some(mut line) = first_line {
+        let first_line = self.horizontals.into_iter().next();
+        if let Some(line) = first_line {
             line.change(records, cfg, dimension);
         }
     }
@@ -1085,7 +1085,7 @@ impl<T, B, L, R, H, V, HLines, VLines, I, D> TableOption<I, D, CompactMultilineC
 where
     HLines: IntoIterator<Item = HorizontalLine> + Clone,
 {
-    fn change(&mut self, records: &mut I, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
+    fn change(self, records: &mut I, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
         self.change(records, cfg.as_mut(), dimension)
     }
 }
diff --git a/tabled/src/settings/style/horizontal_line.rs b/tabled/src/settings/style/horizontal_line.rs
index 1a33b89..bbcdc3f 100644
--- a/tabled/src/settings/style/horizontal_line.rs
+++ b/tabled/src/settings/style/horizontal_line.rs
@@ -49,13 +49,13 @@ impl HorizontalLine {
 
 #[cfg(feature = "std")]
 impl<R, D> TableOption<R, D, ColoredConfig> for HorizontalLine {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         cfg.insert_horizontal_line(self.index, GridLine::from(self.line))
     }
 }
 
 impl<R, D> TableOption<R, D, CompactConfig> for HorizontalLine {
-    fn change(&mut self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
+    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));
         }
@@ -63,7 +63,7 @@ impl<R, D> TableOption<R, D, CompactConfig> for HorizontalLine {
 }
 
 impl<R, D> TableOption<R, D, CompactMultilineConfig> for HorizontalLine {
-    fn change(&mut self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut CompactMultilineConfig, dimension: &mut D) {
         self.change(records, cfg.as_mut(), dimension)
     }
 }
diff --git a/tabled/src/settings/style/raw_style.rs b/tabled/src/settings/style/raw_style.rs
index a31028c..eedb48e 100644
--- a/tabled/src/settings/style/raw_style.rs
+++ b/tabled/src/settings/style/raw_style.rs
@@ -383,13 +383,13 @@ impl<R, D> TableOption<R, D, ColoredConfig> for RawStyle
 where
     R: Records,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dimension: &mut D) {
-        (&*self).change(records, cfg, dimension)
+    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(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         cfg.clear_theme();
 
         cfg.set_borders(self.borders);
diff --git a/tabled/src/settings/style/span_border_correction.rs b/tabled/src/settings/style/span_border_correction.rs
index 7caa6c4..665a127 100644
--- a/tabled/src/settings/style/span_border_correction.rs
+++ b/tabled/src/settings/style/span_border_correction.rs
@@ -80,7 +80,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BorderSpanCorrection
 where
     R: Records + ExactRecords,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let shape = (records.count_rows(), records.count_columns());
         correct_span_styles(cfg, shape);
     }
diff --git a/tabled/src/settings/style/vertical_line.rs b/tabled/src/settings/style/vertical_line.rs
index 52bfd83..adbef2c 100644
--- a/tabled/src/settings/style/vertical_line.rs
+++ b/tabled/src/settings/style/vertical_line.rs
@@ -44,7 +44,7 @@ impl VerticalLine {
 
 #[cfg(feature = "std")]
 impl<R, D> crate::settings::TableOption<R, D, ColoredConfig> for VerticalLine {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         cfg.insert_vertical_line(self.index, VLine::from(self.line));
     }
 }
diff --git a/tabled/src/settings/table_option.rs b/tabled/src/settings/table_option.rs
index d29af1e..e20aa44 100644
--- a/tabled/src/settings/table_option.rs
+++ b/tabled/src/settings/table_option.rs
@@ -3,23 +3,14 @@
 /// [`Table`]: crate::Table
 pub trait TableOption<R, D, C> {
     /// The function allows modification of records and a grid configuration.
-    fn change(&mut self, records: &mut R, cfg: &mut C, dimension: &mut D);
+    fn change(self, records: &mut R, cfg: &mut C, dimension: &mut D);
 }
 
-impl<T, R, D, C> TableOption<R, D, C> for &mut T
+impl<T, R, D, C> TableOption<R, D, C> for &[T]
 where
-    T: TableOption<R, D, C> + ?Sized,
+    for<'a> &'a T: TableOption<R, D, C>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut C, dimension: &mut D) {
-        T::change(self, records, cfg, dimension);
-    }
-}
-
-impl<T, R, D, C> TableOption<R, D, C> for [T]
-where
-    T: TableOption<R, D, C>,
-{
-    fn change(&mut self, records: &mut R, cfg: &mut C, dimension: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut C, dimension: &mut D) {
         for opt in self {
             opt.change(records, cfg, dimension)
         }
@@ -31,7 +22,7 @@ impl<T, R, D, C> TableOption<R, D, C> for Vec<T>
 where
     T: TableOption<R, D, C>,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut C, dimension: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut C, dimension: &mut D) {
         for opt in self {
             opt.change(records, cfg, dimension)
         }
diff --git a/tabled/src/settings/width/justify.rs b/tabled/src/settings/width/justify.rs
index 59d1666..03b2afe 100644
--- a/tabled/src/settings/width/justify.rs
+++ b/tabled/src/settings/width/justify.rs
@@ -40,7 +40,7 @@ use crate::{
 /// ```
 ///
 /// [`Padding`]: crate::settings::Padding
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Justify<W> {
     width: W,
 }
@@ -79,7 +79,7 @@ where
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
     for<'a> &'a R: Records,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let width = self.width.measure(&*records, cfg);
 
         let count_rows = records.count_rows();
@@ -88,8 +88,8 @@ where
         for row in 0..count_rows {
             for col in 0..count_columns {
                 let pos = (row, col).into();
-                CellOption::change(&mut Width::increase(width), records, cfg, pos);
-                CellOption::change(&mut Width::truncate(width), records, cfg, pos);
+                CellOption::change(Width::increase(width), records, cfg, pos);
+                CellOption::change(Width::truncate(width), records, cfg, pos);
             }
         }
     }
diff --git a/tabled/src/settings/width/min_width.rs b/tabled/src/settings/width/min_width.rs
index 203e6ce..1e5f855 100644
--- a/tabled/src/settings/width/min_width.rs
+++ b/tabled/src/settings/width/min_width.rs
@@ -7,7 +7,7 @@ use std::marker::PhantomData;
 use crate::{
     grid::config::ColoredConfig,
     grid::config::Entity,
-    grid::dimension::CompleteDimension,
+    grid::dimension::CompleteDimensionVecRecords,
     grid::records::{ExactRecords, PeekableRecords, Records, RecordsMut},
     grid::util::string::{get_lines, string_width_multiline},
     settings::{
@@ -54,7 +54,7 @@ use super::util::get_table_widths_with_total;
 /// ```
 ///
 /// [`Padding`]: crate::settings::Padding
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct MinWidth<W = usize, P = PriorityNone> {
     width: W,
     fill: char,
@@ -108,7 +108,7 @@ where
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
     for<'a> &'a R: Records,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let width = self.width.measure(&*records, cfg);
 
         let count_rows = records.count_rows();
@@ -132,7 +132,7 @@ where
     }
 }
 
-impl<W, P, R> TableOption<R, CompleteDimension<'static>, ColoredConfig> for MinWidth<W, P>
+impl<W, P, R> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig> for MinWidth<W, P>
 where
     W: Measurement<Width>,
     P: Peaker,
@@ -140,10 +140,10 @@ where
     for<'a> &'a R: Records,
 {
     fn change(
-        &mut self,
+        self,
         records: &mut R,
         cfg: &mut ColoredConfig,
-        dims: &mut CompleteDimension<'static>,
+        dims: &mut CompleteDimensionVecRecords<'static>,
     ) {
         if records.count_rows() == 0 || records.count_columns() == 0 {
             return;
diff --git a/tabled/src/settings/width/truncate.rs b/tabled/src/settings/width/truncate.rs
index 7b13145..7dee244 100644
--- a/tabled/src/settings/width/truncate.rs
+++ b/tabled/src/settings/width/truncate.rs
@@ -7,7 +7,7 @@ use std::{borrow::Cow, iter, marker::PhantomData};
 use crate::{
     grid::{
         config::{ColoredConfig, SpannedConfig},
-        dimension::CompleteDimension,
+        dimension::CompleteDimensionVecRecords,
         records::{EmptyRecords, ExactRecords, PeekableRecords, Records, RecordsMut},
         util::string::{string_width, string_width_multiline},
     },
@@ -38,7 +38,7 @@ use super::util::{cut_str, get_table_widths, get_table_widths_with_total};
 /// ```
 ///
 /// [`Padding`]: crate::settings::Padding
-#[derive(Debug)]
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Truncate<'a, W = usize, P = PriorityNone> {
     width: W,
     suffix: Option<TruncateSuffix<'a>>,
@@ -46,7 +46,7 @@ pub struct Truncate<'a, W = usize, P = PriorityNone> {
     _priority: PhantomData<P>,
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
 struct TruncateSuffix<'a> {
     text: Cow<'a, str>,
     limit: SuffixLimit,
@@ -66,7 +66,7 @@ impl Default for TruncateSuffix<'_> {
 }
 
 /// A suffix limit settings.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum SuffixLimit {
     /// Cut the suffix.
     Cut,
@@ -182,12 +182,7 @@ where
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
     for<'a> &'a R: Records,
 {
-    fn change(
-        &mut self,
-        records: &mut R,
-        cfg: &mut ColoredConfig,
-        entity: papergrid::config::Entity,
-    ) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: papergrid::config::Entity) {
         let available = self.width.measure(&*records, cfg);
 
         let mut width = available;
@@ -298,7 +293,8 @@ fn make_suffix<'a>(suffix: &'a TruncateSuffix<'_>, width: usize) -> (Cow<'a, str
     }
 }
 
-impl<W, P, R> TableOption<R, CompleteDimension<'static>, ColoredConfig> for Truncate<'_, W, P>
+impl<W, P, R> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig>
+    for Truncate<'_, W, P>
 where
     W: Measurement<Width>,
     P: Peaker,
@@ -306,10 +302,10 @@ where
     for<'a> &'a R: Records,
 {
     fn change(
-        &mut self,
+        self,
         records: &mut R,
         cfg: &mut ColoredConfig,
-        dims: &mut CompleteDimension<'static>,
+        dims: &mut CompleteDimensionVecRecords<'static>,
     ) {
         if records.count_rows() == 0 || records.count_columns() == 0 {
             return;
@@ -363,12 +359,11 @@ where
 
     let points = get_decrease_cell_list(cfg, &widths, &min_widths, (count_rows, count_columns));
 
-    let mut truncate = Truncate::new(0);
-    truncate.suffix = suffix;
-    truncate.multiline = multiline;
     for ((row, col), width) in points {
-        truncate.width = width;
-        CellOption::change(&mut truncate, records, cfg, (row, col).into());
+        let mut truncate = Truncate::new(width);
+        truncate.suffix = suffix.clone();
+        truncate.multiline = multiline;
+        CellOption::change(truncate, records, cfg, (row, col).into());
     }
 
     widths
diff --git a/tabled/src/settings/width/width_list.rs b/tabled/src/settings/width/width_list.rs
index 47e4dbc..7547b97 100644
--- a/tabled/src/settings/width/width_list.rs
+++ b/tabled/src/settings/width/width_list.rs
@@ -1,6 +1,8 @@
 use std::iter::FromIterator;
 
-use crate::{grid::dimension::CompleteDimension, grid::records::Records, settings::TableOption};
+use crate::{
+    grid::dimension::CompleteDimensionVecRecords, grid::records::Records, settings::TableOption,
+};
 
 /// A structure used to set [`Table`] width via a list of columns widths.
 ///
@@ -29,15 +31,20 @@ impl FromIterator<usize> for WidthList {
     }
 }
 
-impl<R, C> TableOption<R, CompleteDimension<'static>, C> for WidthList
+impl<R, C> TableOption<R, CompleteDimensionVecRecords<'static>, C> for WidthList
 where
     R: Records,
 {
-    fn change(&mut self, records: &mut R, _: &mut C, dimension: &mut CompleteDimension<'static>) {
+    fn change(
+        self,
+        records: &mut R,
+        _: &mut C,
+        dimension: &mut CompleteDimensionVecRecords<'static>,
+    ) {
         if self.list.len() < records.count_columns() {
             return;
         }
 
-        let _ = dimension.set_widths(self.list.clone());
+        let _ = dimension.set_widths(self.list);
     }
 }
diff --git a/tabled/src/settings/width/wrap.rs b/tabled/src/settings/width/wrap.rs
index a774816..40d1d0c 100644
--- a/tabled/src/settings/width/wrap.rs
+++ b/tabled/src/settings/width/wrap.rs
@@ -7,7 +7,7 @@ use std::marker::PhantomData;
 
 use crate::{
     grid::config::ColoredConfig,
-    grid::dimension::CompleteDimension,
+    grid::dimension::CompleteDimensionVecRecords,
     grid::records::{EmptyRecords, ExactRecords, PeekableRecords, Records, RecordsMut},
     grid::{config::Entity, config::SpannedConfig, util::string::string_width_multiline},
     settings::{
@@ -90,7 +90,14 @@ impl<W, P> Wrap<W, P> {
     }
 }
 
-impl<W, P, R> TableOption<R, CompleteDimension<'static>, ColoredConfig> for Wrap<W, P>
+impl Wrap<(), ()> {
+    /// Wrap a given string
+    pub fn wrap_text(text: &str, width: usize, keeping_words: bool) -> String {
+        wrap_text(text, width, keeping_words)
+    }
+}
+
+impl<W, P, R> TableOption<R, CompleteDimensionVecRecords<'static>, ColoredConfig> for Wrap<W, P>
 where
     W: Measurement<Width>,
     P: Peaker,
@@ -98,10 +105,10 @@ where
     for<'a> &'a R: Records,
 {
     fn change(
-        &mut self,
+        self,
         records: &mut R,
         cfg: &mut ColoredConfig,
-        dims: &mut CompleteDimension<'static>,
+        dims: &mut CompleteDimensionVecRecords<'static>,
     ) {
         if records.count_rows() == 0 || records.count_columns() == 0 {
             return;
@@ -127,7 +134,7 @@ where
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
     for<'a> &'a R: Records,
 {
-    fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
+    fn change(self, records: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let width = self.width.measure(&*records, cfg);
 
         let count_rows = records.count_rows();
@@ -172,11 +179,10 @@ where
 
     let points = get_decrease_cell_list(cfg, &widths, &min_widths, shape);
 
-    let mut wrap = Wrap::new(0);
-    wrap.keep_words = keep_words;
     for ((row, col), width) in points {
-        wrap.width = width;
-        <Wrap as CellOption<R, ColoredConfig>>::change(&mut wrap, records, cfg, (row, col).into());
+        let mut wrap = Wrap::new(width);
+        wrap.keep_words = keep_words;
+        <Wrap as CellOption<_, _>>::change(wrap, records, cfg, (row, col).into());
     }
 
     widths
diff --git a/tabled/src/tables/compact.rs b/tabled/src/tables/compact.rs
index f4aa423..14c1e2b 100644
--- a/tabled/src/tables/compact.rs
+++ b/tabled/src/tables/compact.rs
@@ -167,8 +167,6 @@ impl<I, D> CompactTable<I, D> {
         for<'a> O: TableOption<IterRecords<&'a I>, D, CompactConfig>,
     {
         let mut records = IterRecords::new(&self.records, self.count_columns, self.count_rows);
-
-        let mut option = option;
         option.change(&mut records, &mut self.cfg, &mut self.dims);
 
         self
@@ -305,7 +303,7 @@ const fn create_config() -> CompactConfig {
 }
 
 impl<R, D> TableOption<R, D, CompactConfig> for CompactConfig {
-    fn change(&mut self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
-        *cfg = *self;
+    fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
+        *cfg = self;
     }
 }
diff --git a/tabled/src/tables/iter.rs b/tabled/src/tables/iter.rs
index 1c84217..af485ac 100644
--- a/tabled/src/tables/iter.rs
+++ b/tabled/src/tables/iter.rs
@@ -88,7 +88,7 @@ impl<I> IterTable<I> {
     }
 
     /// With is a generic function which applies options to the [`IterTable`].
-    pub fn with<O>(mut self, mut option: O) -> Self
+    pub fn with<O>(mut self, option: O) -> Self
     where
         for<'a> O: TableOption<IterRecords<&'a I>, StaticDimension, CompactConfig>,
     {
diff --git a/tabled/src/tables/table.rs b/tabled/src/tables/table.rs
index 7e1164d..929130e 100644
--- a/tabled/src/tables/table.rs
+++ b/tabled/src/tables/table.rs
@@ -1,28 +1,27 @@
 //! This module contains a main table representation [`Table`].
 
 use core::ops::DerefMut;
-use std::{borrow::Cow, collections::HashMap, fmt, iter::FromIterator};
+use std::{borrow::Cow, fmt, iter::FromIterator};
 
 use crate::{
     builder::Builder,
     grid::{
+        colors::NoColors,
         config::{
-            AlignmentHorizontal, ColoredConfig, CompactConfig, Entity, Formatting, Indent, Sides,
-            SpannedConfig,
+            AlignmentHorizontal, ColorMap, ColoredConfig, CompactConfig, Entity, Formatting,
+            Indent, Sides, SpannedConfig,
+        },
+        dimension::{CompleteDimensionVecRecords, Dimension, Estimate, PeekableDimension},
+        records::{
+            vec_records::{CellInfo, VecRecords},
+            ExactRecords, Records,
         },
-        dimension::{CompleteDimension, PeekableDimension},
-        dimension::{Dimension, Estimate},
-        records::{vec_records::VecRecords, ExactRecords, Records},
         PeekableGrid,
     },
     settings::{Style, TableOption},
     Tabled,
 };
 
-use papergrid::{
-    color::AnsiColor, colors::NoColors, config::Position, records::vec_records::CellInfo,
-};
-
 /// The structure provides an interface for building a table for types that implements [`Tabled`].
 ///
 /// To build a string representation of a table you must use a [`std::fmt::Display`].
@@ -60,7 +59,7 @@ use papergrid::{
 pub struct Table {
     records: VecRecords<CellInfo<String>>,
     config: ColoredConfig,
-    dimension: CompleteDimension<'static>,
+    dimension: CompleteDimensionVecRecords<'static>,
 }
 
 impl Table {
@@ -97,8 +96,8 @@ impl Table {
 
         Self {
             records,
-            config: ColoredConfig::new(configure_grid(), HashMap::default()),
-            dimension: CompleteDimension::default(),
+            config: ColoredConfig::new(configure_grid()),
+            dimension: CompleteDimensionVecRecords::default(),
         }
     }
 
@@ -178,12 +177,15 @@ impl Table {
     /// It applies settings immediately.
     pub fn with<O>(&mut self, option: O) -> &mut Self
     where
-        O: TableOption<VecRecords<CellInfo<String>>, CompleteDimension<'static>, ColoredConfig>,
+        O: TableOption<
+            VecRecords<CellInfo<String>>,
+            CompleteDimensionVecRecords<'static>,
+            ColoredConfig,
+        >,
     {
         self.dimension.clear_width();
         self.dimension.clear_height();
 
-        let mut option = option;
         option.change(&mut self.records, &mut self.config, &mut self.dimension);
 
         self
@@ -212,7 +214,7 @@ impl Table {
 
     /// Returns total widths of a table, including margin and horizontal lines.
     pub fn total_height(&self) -> usize {
-        let mut dims = CompleteDimension::from_origin(&self.dimension);
+        let mut dims = CompleteDimensionVecRecords::from_origin(&self.dimension);
         dims.estimate(&self.records, self.config.as_ref());
 
         let total = (0..self.count_rows())
@@ -227,7 +229,7 @@ impl Table {
 
     /// Returns total widths of a table, including margin and vertical lines.
     pub fn total_width(&self) -> usize {
-        let mut dims = CompleteDimension::from_origin(&self.dimension);
+        let mut dims = CompleteDimensionVecRecords::from_origin(&self.dimension);
         dims.estimate(&self.records, self.config.as_ref());
 
         let total = (0..self.count_columns())
@@ -255,8 +257,8 @@ impl Default for Table {
     fn default() -> Self {
         Self {
             records: VecRecords::default(),
-            config: ColoredConfig::new(configure_grid(), HashMap::default()),
-            dimension: CompleteDimension::default(),
+            config: ColoredConfig::new(configure_grid()),
+            dimension: CompleteDimensionVecRecords::default(),
         }
     }
 }
@@ -301,44 +303,42 @@ impl From<Builder> for Table {
 
         Self {
             records,
-            config: ColoredConfig::new(configure_grid(), HashMap::default()),
-            dimension: CompleteDimension::default(),
+            config: ColoredConfig::new(configure_grid()),
+            dimension: CompleteDimensionVecRecords::default(),
         }
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for CompactConfig {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        *cfg.deref_mut() = (*self).into();
+impl From<Table> for Builder {
+    fn from(val: Table) -> Self {
+        let count_columns = val.count_columns();
+        let data: Vec<Vec<CellInfo<String>>> = val.records.into();
+        let mut builder = Builder::from(data);
+        let _ = builder.hint_column_size(count_columns);
+        builder
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for &CompactConfig {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        *cfg.deref_mut() = (**self).into();
+impl<R, D> TableOption<R, D, ColoredConfig> for CompactConfig {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        *cfg.deref_mut() = self.into();
     }
 }
 
 impl<R, D> TableOption<R, D, ColoredConfig> for ColoredConfig {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        *cfg = self.clone();
-    }
-}
-
-impl<R, D> TableOption<R, D, ColoredConfig> for &ColoredConfig {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        *cfg = self.clone();
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        *cfg = self;
     }
 }
 
 impl<R, D> TableOption<R, D, ColoredConfig> for SpannedConfig {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        *cfg.deref_mut() = self.clone();
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        *cfg.deref_mut() = self;
     }
 }
 
 impl<R, D> TableOption<R, D, ColoredConfig> for &SpannedConfig {
-    fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         *cfg.deref_mut() = self.clone();
     }
 }
@@ -444,7 +444,7 @@ fn print_grid<F: fmt::Write, D: Dimension>(
     records: &VecRecords<CellInfo<String>>,
     cfg: &SpannedConfig,
     dims: D,
-    colors: &HashMap<Position, AnsiColor<'static>>,
+    colors: &ColorMap,
 ) -> fmt::Result {
     if !colors.is_empty() {
         PeekableGrid::new(records, cfg, &dims, colors).build(f)
diff --git a/tabled/src/tables/table_pool.rs b/tabled/src/tables/table_pool.rs
index c9b0da4..07d2a54 100644
--- a/tabled/src/tables/table_pool.rs
+++ b/tabled/src/tables/table_pool.rs
@@ -167,7 +167,7 @@ impl PoolTable {
     ///      ╚═════╩═════╩═╝"
     /// )
     /// ```
-    pub fn with<O>(&mut self, mut option: O) -> &mut Self
+    pub fn with<O>(&mut self, option: O) -> &mut Self
     where
         O: TableOption<EmptyRecords, PoolTableDimension, CompactMultilineConfig>,
     {
@@ -220,36 +220,38 @@ fn configure_grid() -> CompactMultilineConfig {
 }
 
 impl<R, C> TableOption<R, PoolTableDimension, C> for PoolTableDimension {
-    fn change(&mut self, _: &mut R, _: &mut C, dimension: &mut PoolTableDimension) {
-        *dimension = *self;
+    fn change(self, _: &mut R, _: &mut C, dimension: &mut PoolTableDimension) {
+        *dimension = self;
     }
 }
 
 impl<R, D> TableOption<R, D, CompactMultilineConfig> for CompactMultilineConfig {
-    fn change(&mut self, _: &mut R, config: &mut CompactMultilineConfig, _: &mut D) {
-        *config = *self;
+    fn change(self, _: &mut R, config: &mut CompactMultilineConfig, _: &mut D) {
+        *config = self;
     }
 }
 
 mod print {
-    use core::iter::FromIterator;
     use std::{cmp::max, collections::HashMap, iter::repeat};
 
-    use papergrid::config::{spanned::SpannedConfig, Borders};
+    use papergrid::{
+        color::StaticColor,
+        config::{Border, Borders},
+        util::string::string_width_multiline,
+    };
 
     use crate::{
         builder::Builder,
         grid::{
             config::{
                 AlignmentHorizontal, AlignmentVertical, ColoredConfig, CompactMultilineConfig,
-                Offset,
+                Indent, Offset, Sides,
             },
             dimension::{Dimension, DimensionPriority, Estimate, PoolTableDimension},
             records::Records,
             util::string::{count_lines, get_lines, string_dimension, string_width},
         },
         settings::{Padding, Style, TableOption},
-        Table,
     };
 
     use super::TableValue;
@@ -308,8 +310,19 @@ mod print {
         };
 
         let data = _build_table(val, cfg, &dims, dims_priority, ctx);
+        let mut table = data.content;
+
+        let margin = cfg.get_margin();
+        let has_margin = margin.top.size > 0
+            || margin.bottom.size > 0
+            || margin.left.size > 0
+            || margin.right.size > 0;
+        if has_margin {
+            let color = convert_border_colors(cfg.get_margin_color());
+            table = set_margin(&table, *margin, color);
+        }
 
-        data.content
+        table
     }
 
     fn _build_table(
@@ -520,30 +533,458 @@ mod print {
     }
 
     fn generate_value_cell(
-        value: &str,
+        text: &str,
         cfg: &CompactMultilineConfig,
         ctx: PrintContext,
     ) -> CellData {
         let width = ctx.size.width;
         let height = ctx.size.height;
+        let table = generate_value_table(text, cfg, ctx);
+        CellData::new(table, vec![width], vec![height])
+    }
 
-        let config: SpannedConfig = (*cfg).into();
+    fn generate_value_table(
+        text: &str,
+        cfg: &CompactMultilineConfig,
+        mut ctx: PrintContext,
+    ) -> String {
+        if ctx.size.width == 0 || ctx.size.height == 0 {
+            return String::new();
+        }
+
+        let halignment = cfg.get_alignment_horizontal();
+        let valignment = cfg.get_alignment_vertical();
+        let pad = cfg.get_padding();
+        let pad_color = cfg.get_padding_color();
+        let pad_color = convert_border_colors(pad_color);
+        let lines_alignemnt = cfg.get_formatting().allow_lines_alignment;
 
-        let value = config_string(value, cfg, width, height);
-        let mut table = Table::from_iter([[value]]);
+        let mut borders = *cfg.get_borders();
 
-        let _ = table.with(config);
-        let _ = table.with(ConfigCell(ctx));
+        let bottom_intesection = cfg.get_borders().bottom_intersection.unwrap_or(' ');
+        let mut horizontal_splits = short_splits(&mut ctx.intersections_horizontal, ctx.size.width);
+        squash_splits(&mut horizontal_splits);
 
-        let table = table.to_string();
+        let right_intersection = borders.right_intersection.unwrap_or(' ');
+        let mut vertical_splits = short_splits(&mut ctx.intersections_vertical, ctx.size.height);
+        squash_splits(&mut vertical_splits);
 
-        CellData::new(table, vec![width], vec![height])
+        config_borders(&mut borders, &ctx);
+        let border = create_border(borders);
+
+        let borders_colors = *cfg.get_borders_color();
+        let border_color = create_border(borders_colors);
+
+        let mut height = ctx.size.height;
+        height -= pad.top.size + pad.bottom.size;
+
+        let mut width = ctx.size.width;
+        width -= pad.left.size + pad.right.size;
+
+        let count_lines = count_lines(text);
+        let (top, bottom) = indent_vertical(valignment, height, count_lines);
+
+        let mut buf = String::new();
+        print_top_line(
+            &mut buf,
+            border,
+            border_color,
+            &horizontal_splits,
+            bottom_intesection,
+            ctx.size.width,
+        );
+
+        let mut line_index = 0;
+        let mut vertical_splits = &vertical_splits[..];
+
+        for _ in 0..top {
+            let mut border = border;
+            if vertical_splits.first() == Some(&line_index) {
+                border.left = Some(right_intersection);
+                vertical_splits = &vertical_splits[1..];
+            }
+
+            print_line(&mut buf, border, border_color, None, ' ', ctx.size.width);
+            line_index += 1;
+        }
+
+        for _ in 0..pad.top.size {
+            let mut border = border;
+            if vertical_splits.first() == Some(&line_index) {
+                border.left = Some(right_intersection);
+                vertical_splits = &vertical_splits[1..];
+            }
+
+            print_line(
+                &mut buf,
+                border,
+                border_color,
+                pad_color.top,
+                pad.top.fill,
+                ctx.size.width,
+            );
+            line_index += 1;
+        }
+
+        if lines_alignemnt {
+            for line in get_lines(text) {
+                let line_width = string_width(&line);
+                let (left, right) = indent_horizontal(halignment, width, line_width);
+
+                if border.has_left() {
+                    let mut c = border.left.unwrap_or(' ');
+                    if vertical_splits.first() == Some(&line_index) {
+                        c = right_intersection;
+                        vertical_splits = &vertical_splits[1..];
+                    }
+
+                    print_char(&mut buf, c, border_color.left);
+                }
+
+                print_chars(&mut buf, pad.left.fill, pad_color.left, pad.left.size);
+                buf.extend(repeat(' ').take(left));
+                buf.push_str(&line);
+                buf.extend(repeat(' ').take(right));
+                print_chars(&mut buf, pad.right.fill, pad_color.right, pad.right.size);
+
+                if border.has_right() {
+                    print_char(&mut buf, border.right.unwrap_or(' '), border_color.right);
+                }
+
+                buf.push('\n');
+
+                line_index += 1;
+            }
+        } else {
+            let text_width = string_width_multiline(text);
+            let (left, _) = indent_horizontal(halignment, width, text_width);
+
+            for line in get_lines(text) {
+                let line_width = string_width(&line);
+                let right = width - line_width - left;
+
+                if border.has_left() {
+                    let mut c = border.left.unwrap_or(' ');
+                    if vertical_splits.first() == Some(&line_index) {
+                        c = right_intersection;
+                        vertical_splits = &vertical_splits[1..];
+                    }
+
+                    print_char(&mut buf, c, border_color.left);
+                }
+
+                print_chars(&mut buf, pad.left.fill, pad_color.left, pad.left.size);
+                buf.extend(repeat(' ').take(left));
+                buf.push_str(&line);
+                buf.extend(repeat(' ').take(right));
+                print_chars(&mut buf, pad.right.fill, pad_color.right, pad.right.size);
+
+                if border.has_right() {
+                    print_char(&mut buf, border.right.unwrap_or(' '), border_color.right);
+                }
+
+                buf.push('\n');
+
+                line_index += 1;
+            }
+        }
+
+        for _ in 0..pad.bottom.size {
+            let mut border = border;
+            if vertical_splits.first() == Some(&line_index) {
+                border.left = Some(right_intersection);
+                vertical_splits = &vertical_splits[1..];
+            }
+
+            print_line(
+                &mut buf,
+                border,
+                border_color,
+                pad_color.bottom,
+                pad.bottom.fill,
+                ctx.size.width,
+            );
+
+            line_index += 1;
+        }
+
+        for _ in 0..bottom {
+            let mut border = border;
+            if vertical_splits.first() == Some(&line_index) {
+                border.left = Some(right_intersection);
+                vertical_splits = &vertical_splits[1..];
+            }
+
+            print_line(&mut buf, border, border_color, None, ' ', ctx.size.width);
+            line_index += 1;
+        }
+
+        print_bottom_line(&mut buf, border, border_color, ctx.size.width);
+
+        let _ = buf.remove(buf.len() - 1);
+
+        buf
+    }
+
+    fn print_chars(buf: &mut String, c: char, color: Option<StaticColor>, width: usize) {
+        match color {
+            Some(color) => {
+                buf.push_str(color.get_prefix());
+                buf.extend(repeat(c).take(width));
+                buf.push_str(color.get_suffix());
+            }
+            None => buf.extend(repeat(c).take(width)),
+        }
+    }
+
+    fn print_char(buf: &mut String, c: char, color: Option<StaticColor>) {
+        match color {
+            Some(color) => {
+                buf.push_str(color.get_prefix());
+                buf.push(c);
+                buf.push_str(color.get_suffix());
+            }
+            None => buf.push(c),
+        }
+    }
+
+    fn print_line(
+        buf: &mut String,
+        border: Border<char>,
+        border_color: Border<StaticColor>,
+        color: Option<StaticColor>,
+        c: char,
+        width: usize,
+    ) {
+        if border.has_left() {
+            let c = border.left.unwrap_or(' ');
+            print_char(buf, c, border_color.left);
+        }
+
+        print_chars(buf, c, color, width);
+
+        if border.has_right() {
+            let c = border.right.unwrap_or(' ');
+            print_char(buf, c, border_color.right);
+        }
+
+        buf.push('\n');
+    }
+
+    fn print_top_line(
+        buf: &mut String,
+        border: Border<char>,
+        color: Border<StaticColor>,
+        splits: &[usize],
+        split_char: char,
+        width: usize,
+    ) {
+        if !border.has_top() {
+            return;
+        }
+
+        let mut used_color: Option<StaticColor> = None;
+
+        if border.has_left() {
+            if let Some(color) = color.left_top_corner {
+                used_color = Some(color);
+                buf.push_str(color.get_prefix());
+            }
+
+            let c = border.left_top_corner.unwrap_or(' ');
+            buf.push(c);
+        }
+
+        if let Some(color) = color.top {
+            match used_color {
+                Some(used) => {
+                    if used != color {
+                        buf.push_str(used.get_suffix());
+                        buf.push_str(color.get_prefix());
+                    }
+                }
+                None => {
+                    buf.push_str(color.get_prefix());
+                    used_color = Some(color);
+                }
+            }
+        }
+
+        let c = border.top.unwrap_or(' ');
+        if splits.is_empty() {
+            buf.extend(repeat(c).take(width));
+        } else {
+            let mut splits = splits;
+            for i in 0..width {
+                if splits.first() == Some(&i) {
+                    buf.push(split_char);
+                    splits = &splits[1..];
+                } else {
+                    buf.push(c);
+                }
+            }
+        }
+
+        if border.has_right() {
+            if let Some(color) = color.right_top_corner {
+                match used_color {
+                    Some(used) => {
+                        if used != color {
+                            buf.push_str(used.get_suffix());
+                            buf.push_str(color.get_prefix());
+                        }
+                    }
+                    None => {
+                        buf.push_str(color.get_prefix());
+                        used_color = Some(color);
+                    }
+                }
+            }
+
+            let c = border.right_top_corner.unwrap_or(' ');
+            buf.push(c);
+        }
+
+        if let Some(used) = used_color {
+            buf.push_str(used.get_suffix());
+        }
+
+        buf.push('\n');
+    }
+
+    fn print_bottom_line(
+        buf: &mut String,
+        border: Border<char>,
+        color: Border<StaticColor>,
+        width: usize,
+    ) {
+        if !border.has_bottom() {
+            return;
+        }
+
+        let mut used_color: Option<StaticColor> = None;
+
+        if border.has_left() {
+            if let Some(color) = color.left_bottom_corner {
+                used_color = Some(color);
+                buf.push_str(color.get_prefix());
+            }
+
+            let c = border.left_bottom_corner.unwrap_or(' ');
+            buf.push(c);
+        }
+
+        if let Some(color) = color.bottom {
+            match used_color {
+                Some(used) => {
+                    if used != color {
+                        buf.push_str(used.get_suffix());
+                        buf.push_str(color.get_prefix());
+                    }
+                }
+                None => {
+                    buf.push_str(color.get_prefix());
+                    used_color = Some(color);
+                }
+            }
+        }
+
+        let c = border.bottom.unwrap_or(' ');
+        buf.extend(repeat(c).take(width));
+
+        if border.has_right() {
+            if let Some(color) = color.right_bottom_corner {
+                match used_color {
+                    Some(used) => {
+                        if used != color {
+                            buf.push_str(used.get_suffix());
+                            buf.push_str(color.get_prefix());
+                        }
+                    }
+                    None => {
+                        buf.push_str(color.get_prefix());
+                        used_color = Some(color);
+                    }
+                }
+            }
+
+            let c = border.right_bottom_corner.unwrap_or(' ');
+            buf.push(c);
+        }
+
+        if let Some(used) = used_color {
+            buf.push_str(used.get_suffix());
+        }
+
+        buf.push('\n');
+    }
+
+    fn create_border<T>(borders: Borders<T>) -> Border<T> {
+        Border {
+            top: borders.top,
+            bottom: borders.bottom,
+            left: borders.left,
+            right: borders.right,
+            left_top_corner: borders.top_left,
+            left_bottom_corner: borders.bottom_left,
+            right_top_corner: borders.top_right,
+            right_bottom_corner: borders.bottom_right,
+        }
+    }
+
+    fn config_borders(borders: &mut Borders<char>, ctx: &PrintContext) {
+        // set top_left
+        {
+            if ctx.kv && ctx.kv_is_first {
+                borders.top_left = borders.top_intersection;
+            }
+
+            if ctx.kv && !ctx.kv_is_first {
+                borders.top_left = borders.intersection;
+            }
+
+            if ctx.kv && ctx.list && !ctx.list_is_first {
+                borders.top_left = borders.left_intersection;
+            }
+
+            if ctx.is_first_col && !ctx.is_first_row {
+                borders.top_left = borders.left_intersection;
+            }
+
+            if ctx.lean_top {
+                borders.top_left = borders.top_intersection;
+            }
+
+            if ctx.top_left {
+                borders.top_left = borders.left_intersection;
+            }
+
+            if ctx.top_intersection {
+                borders.top_left = borders.intersection;
+            }
+        }
+
+        if ctx.is_last_col && !ctx.is_first_row {
+            borders.top_right = borders.right_intersection;
+        }
+
+        if !ctx.is_first_col && ctx.is_last_row {
+            borders.bottom_left = borders.bottom_intersection;
+        }
+
+        if !ctx.is_last_row || ctx.no_bottom {
+            cfg_no_bottom_borders(borders);
+        }
+
+        if ctx.no_right {
+            cfg_no_right_borders(borders);
+        }
     }
 
     struct ConfigCell(PrintContext);
 
     impl<R, D> TableOption<R, D, ColoredConfig> for ConfigCell {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             {
                 // we set a horizontal lines to borders to not complicate logic with cleaning it
 
@@ -564,7 +1005,7 @@ mod print {
                 cfg.set_borders(borders);
             }
 
-            let ctx = &mut self.0;
+            let mut ctx = self.0;
 
             let has_vertical = cfg.get_borders().has_left();
             if !ctx.intersections_horizontal.is_empty() && has_vertical {
@@ -577,7 +1018,7 @@ mod print {
 
             let has_horizontal = cfg.get_borders().has_top();
             if !ctx.intersections_vertical.is_empty() && has_horizontal {
-                let mut splits = short_splits(&mut ctx.intersections_vertical, ctx.size.width);
+                let mut splits = short_splits(&mut ctx.intersections_vertical, ctx.size.height);
                 squash_splits(&mut splits);
 
                 let c = cfg.get_borders().right_intersection.unwrap_or(' ');
@@ -669,7 +1110,7 @@ mod print {
     struct NoTopBorders;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for NoTopBorders {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top = None;
             borders.top_intersection = None;
@@ -683,7 +1124,7 @@ mod print {
     struct NoBottomBorders;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for NoBottomBorders {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom = None;
             borders.bottom_intersection = None;
@@ -697,7 +1138,7 @@ mod print {
     struct NoRightBorders;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for NoRightBorders {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_right = None;
             borders.bottom_right = None;
@@ -711,7 +1152,7 @@ mod print {
     struct NoLeftBorders;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for NoLeftBorders {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = None;
             borders.bottom_left = None;
@@ -725,7 +1166,7 @@ mod print {
     struct TopLeftChangeTopIntersection;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeTopIntersection {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = borders.top_intersection;
 
@@ -736,7 +1177,7 @@ mod print {
     struct TopLeftChangeIntersection;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeIntersection {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = borders.intersection;
 
@@ -747,7 +1188,7 @@ mod print {
     struct TopLeftChangeToLeft;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeToLeft {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = borders.left_intersection;
 
@@ -758,7 +1199,7 @@ mod print {
     struct TopRightChangeToRight;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for TopRightChangeToRight {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_right = borders.right_intersection;
 
@@ -769,7 +1210,7 @@ mod print {
     struct BottomLeftChangeSplit;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplit {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_left = borders.left_intersection;
 
@@ -780,7 +1221,7 @@ mod print {
     struct BottomLeftChangeSplitToIntersection;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplitToIntersection {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_left = borders.intersection;
 
@@ -791,7 +1232,7 @@ mod print {
     struct BottomRightChangeToRight;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for BottomRightChangeToRight {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_right = borders.right_intersection;
 
@@ -802,7 +1243,7 @@ mod print {
     struct BottomLeftChangeToBottomIntersection;
 
     impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeToBottomIntersection {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_left = borders.bottom_intersection;
 
@@ -818,7 +1259,7 @@ mod print {
         for<'a> &'a R: Records,
         for<'a> D: Dimension + Estimate<&'a R, ColoredConfig>,
     {
-        fn change(&mut self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
+        fn change(self, records: &mut R, cfg: &mut ColoredConfig, dims: &mut D) {
             dims.estimate(&*records, cfg);
 
             let table_width = (0..records.count_columns())
@@ -844,7 +1285,7 @@ mod print {
     struct SetTopChars<'a>(&'a [usize], char);
 
     impl<R, D> TableOption<R, D, ColoredConfig> for SetTopChars<'_> {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             for &split in self.0 {
                 let offset = split;
                 cfg.set_horizontal_char((0, 0), self.1, Offset::Begin(offset));
@@ -855,7 +1296,7 @@ mod print {
     struct SetLeftChars<'a>(&'a [usize], char);
 
     impl<R, D> TableOption<R, D, ColoredConfig> for SetLeftChars<'_> {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             for &offset in self.0 {
                 cfg.set_vertical_char((0, 0), self.1, Offset::Begin(offset));
             }
@@ -864,16 +1305,16 @@ mod print {
 
     struct GetTopIntersection(char);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for GetTopIntersection {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetTopIntersection {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             self.0 = cfg.get_borders().top_intersection.unwrap_or(' ');
         }
     }
 
     struct GetBottomIntersection(char);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for GetBottomIntersection {
-        fn change(&mut self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
+    impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetBottomIntersection {
+        fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             self.0 = cfg.get_borders().bottom_intersection.unwrap_or(' ');
         }
     }
@@ -1025,51 +1466,6 @@ mod print {
         (val, rest)
     }
 
-    fn config_string(
-        value: &str,
-        cfg: &CompactMultilineConfig,
-        width: usize,
-        height: usize,
-    ) -> String {
-        let width = width - get_padding_horizontal(cfg);
-        let height = height - get_padding_vertical(cfg);
-        let ah = cfg.get_alignment_horizontal();
-        let av = cfg.get_alignment_vertical();
-        set_string_dimension(value, width, height, ah, av)
-    }
-
-    fn set_string_dimension(
-        text: &str,
-        width: usize,
-        height: usize,
-        ah: AlignmentHorizontal,
-        av: AlignmentVertical,
-    ) -> String {
-        let mut out = Vec::with_capacity(height);
-
-        let count_lines = count_lines(text);
-
-        let (top, bottom) = indent_vertical(av, height, count_lines);
-
-        out.extend(repeat(String::new()).take(top));
-
-        for line in get_lines(text) {
-            let w = string_width(&line);
-            let (left, right) = indent_horizontal(ah, width, w);
-
-            let mut buf = String::new();
-            buf.extend(repeat(' ').take(left));
-            buf.push_str(&line);
-            buf.extend(repeat(' ').take(right));
-
-            out.push(buf);
-        }
-
-        out.extend(repeat(String::new()).take(bottom));
-
-        out.join("\n")
-    }
-
     fn indent_vertical(al: AlignmentVertical, available: usize, real: usize) -> (usize, usize) {
         let top = indent_top(al, available, real);
         let bottom = available - real - top;
@@ -1162,4 +1558,50 @@ mod print {
     fn squash_splits(splits: &mut [usize]) {
         splits.iter_mut().enumerate().for_each(|(i, s)| *s += i);
     }
+
+    fn set_margin(table: &str, margin: Sides<Indent>, color: Sides<Option<StaticColor>>) -> String {
+        if table.is_empty() {
+            return String::new();
+        }
+
+        let mut buf = String::new();
+        let width = string_width_multiline(table);
+        let top_color = color.top;
+        let bottom_color = color.bottom;
+        let left_color = color.left;
+        let right_color = color.right;
+        for _ in 0..margin.top.size {
+            print_chars(&mut buf, margin.left.fill, left_color, margin.left.size);
+            print_chars(&mut buf, margin.top.fill, top_color, width);
+            print_chars(&mut buf, margin.right.fill, right_color, margin.right.size);
+            buf.push('\n');
+        }
+
+        for line in get_lines(table) {
+            print_chars(&mut buf, margin.left.fill, left_color, margin.left.size);
+            buf.push_str(&line);
+            print_chars(&mut buf, margin.right.fill, right_color, margin.right.size);
+            buf.push('\n');
+        }
+
+        for _ in 0..margin.bottom.size {
+            print_chars(&mut buf, margin.left.fill, left_color, margin.left.size);
+            print_chars(&mut buf, margin.bottom.fill, bottom_color, width);
+            print_chars(&mut buf, margin.right.fill, right_color, margin.right.size);
+            buf.push('\n');
+        }
+
+        let _ = buf.remove(buf.len() - 1);
+
+        buf
+    }
+
+    fn convert_border_colors(pad_color: Sides<StaticColor>) -> Sides<Option<StaticColor>> {
+        Sides::new(
+            (!pad_color.left.is_empty()).then(|| pad_color.left),
+            (!pad_color.right.is_empty()).then(|| pad_color.right),
+            (!pad_color.top.is_empty()).then(|| pad_color.top),
+            (!pad_color.bottom.is_empty()).then(|| pad_color.bottom),
+        )
+    }
 }


Test patch:
diff --git a/json_to_table/tests/test_config.rs b/json_to_table/tests/test_config.rs
index 464b245..a827aa1 100644
--- a/json_to_table/tests/test_config.rs
+++ b/json_to_table/tests/test_config.rs
@@ -148,7 +148,7 @@ fn color_test() {
 
     let mut cfg = SpannedConfig::default();
     cfg.set_border_color_global(AnsiColor::new("\u{1b}[34m".into(), "\u{1b}[39m".into()));
-    let cfg = ColoredConfig::new(cfg, Default::default());
+    let cfg = ColoredConfig::new(cfg);
 
     let table = json_to_table(&value)
         .with(cfg)
diff --git a/static_table/tests/pool_table.rs b/static_table/tests/pool_table.rs
index 4a5eaac..2b3ff3f 100644
--- a/static_table/tests/pool_table.rs
+++ b/static_table/tests/pool_table.rs
@@ -335,19 +335,15 @@ fn pool_table_with_theme_padding_margin() {
         THEME = "ROUNDED"
     );
     let expected = concat!(
-        "                           \n",
-        " ╭─────  ┬─────  ┬───────╮ \n",
-        " │  1    │  2    │  123  │ \n",
-        "                           \n",
-        "                           \n",
-        "  ─────   ─────   ───────  \n",
-        " │  1    │  2    │  123  │ \n",
-        "                           \n",
-        "                           \n",
-        "  ─────   ─────   ───────  \n",
-        " │  1    │  2    │  123  │ \n",
-        " ├─────  ┴─────  ┴───────┤ \n",
-        "                           ",
+        "                       \n",
+        " ╭─────┬─────┬───────╮ \n",
+        " │  1  │  2  │  123  │ \n",
+        "  ───── ───── ───────  \n",
+        " │  1  │  2  │  123  │ \n",
+        "  ───── ───── ───────  \n",
+        " │  1  │  2  │  123  │ \n",
+        " ╰─────┴─────┴───────╯ \n",
+        "                       ",
     );
     assert_eq!(table, expected);
 }
diff --git a/tabled/tests/format_test.rs b/tabled/tests/format_test.rs
index bea4858..053e9b4 100644
--- a/tabled/tests/format_test.rs
+++ b/tabled/tests/format_test.rs
@@ -214,7 +214,7 @@ test_table!(
 
 test_table!(
     formatting_content_str_test,
-    create_table::<3, 3>().with(Modify::new(Segment::all()).with(Format::content(|_| "Hello World"))),
+    create_table::<3, 3>().with(Modify::new(Segment::all()).with(Format::content(|_| String::from("Hello World")))),
     "+-------------+-------------+-------------+-------------+"
     "| Hello World | Hello World | Hello World | Hello World |"
     "+-------------+-------------+-------------+-------------+"
diff --git a/tabled/tests/pool_table.rs b/tabled/tests/pool_table.rs
index 889f73c..5b0045e 100644
--- a/tabled/tests/pool_table.rs
+++ b/tabled/tests/pool_table.rs
@@ -4,11 +4,14 @@ mod util;
 
 use tabled::{
     grid::dimension::{DimensionPriority, PoolTableDimension},
-    settings::{Alignment, Margin, Padding, Style},
+    settings::{formatting::AlignmentStrategy, Alignment, Margin, Padding, Style},
     tables::{PoolTable, TableValue},
 };
 use util::{create_matrix, test_table};
 
+#[cfg(feature = "color")]
+use tabled::grid::color::StaticColor;
+
 test_table!(
     pool_table,
     PoolTable::new(create_matrix::<3, 3>()),
@@ -306,37 +309,66 @@ test_table!(
     "+------+------+------+"
 );
 
+#[cfg(feature = "color")]
+test_table!(
+    pool_table_padding_2,
+    PoolTable::new(create_matrix::<3, 3>())
+        .with(Padding::new(1, 2, 3, 4)
+            .fill('!', '@', '#', '$')
+            .colorize(
+                StaticColor::new("\u{1b}[34m", "\u{1b}[39m"),
+                StaticColor::new("\u{1b}[34m", "\u{1b}[39m"),
+                StaticColor::new("\u{1b}[34m", "\u{1b}[39m"),
+                StaticColor::new("\u{1b}[34m", "\u{1b}[39m"),
+            )
+        ),
+    "+------+------+------+"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m!\u{1b}[39m0-0\u{1b}[34m@@\u{1b}[39m|\u{1b}[34m!\u{1b}[39m0-1\u{1b}[34m@@\u{1b}[39m|\u{1b}[34m!\u{1b}[39m0-2\u{1b}[34m@@\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "+------+------+------+"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m!\u{1b}[39m1-0\u{1b}[34m@@\u{1b}[39m|\u{1b}[34m!\u{1b}[39m1-1\u{1b}[34m@@\u{1b}[39m|\u{1b}[34m!\u{1b}[39m1-2\u{1b}[34m@@\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "+------+------+------+"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|\u{1b}[34m######\u{1b}[39m|"
+    "|\u{1b}[34m!\u{1b}[39m2-0\u{1b}[34m@@\u{1b}[39m|\u{1b}[34m!\u{1b}[39m2-1\u{1b}[34m@@\u{1b}[39m|\u{1b}[34m!\u{1b}[39m2-2\u{1b}[34m@@\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|\u{1b}[34m$$$$$$\u{1b}[39m|"
+    "+------+------+------+"
+);
+
 test_table!(
     pool_table_margin,
-    PoolTable::new(create_matrix::<3, 3>()).with(Margin::new(1, 2, 3, 4)),
-    "                            "
-    "                            "
-    "                            "
-    " +-----   +-----   +-----+  "
-    " | 0-0    | 0-1    | 0-2 |  "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    " +-----   +-----   +-----+  "
-    " | 1-0    | 1-1    | 1-2 |  "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
-    " +-----   +-----   +-----+  "
-    " | 2-0    | 2-1    | 2-2 |  "
-    " +-----   +-----   +-----+  "
-    "                            "
-    "                            "
-    "                            "
-    "                            "
+    PoolTable::new(create_matrix::<3, 3>()).with(Margin::new(1, 2, 3, 4).fill('!', '@', '#', '$')),
+    "!###################@@"
+    "!###################@@"
+    "!###################@@"
+    "!+-----+-----+-----+@@"
+    "!| 0-0 | 0-1 | 0-2 |@@"
+    "!+-----+-----+-----+@@"
+    "!| 1-0 | 1-1 | 1-2 |@@"
+    "!+-----+-----+-----+@@"
+    "!| 2-0 | 2-1 | 2-2 |@@"
+    "!+-----+-----+-----+@@"
+    "!$$$$$$$$$$$$$$$$$$$@@"
+    "!$$$$$$$$$$$$$$$$$$$@@"
+    "!$$$$$$$$$$$$$$$$$$$@@"
+    "!$$$$$$$$$$$$$$$$$$$@@"
 );
 
 test_table!(
@@ -394,6 +426,30 @@ test_table!(
     ])
     .with(Alignment::right()),
     "+------------------------+----------+---+"
+    "| 1                      | 2        | 3 |"
+    "|                        | 2        | 3 |"
+    "|                        |          | 3 |"
+    "+-------------+----------+-+--------+---+"
+    "|           3 |          2 |          1 |"
+    "|           3 |          2 |            |"
+    "|           3 |            |            |"
+    "+------+------+------------+-----+------+"
+    "|    1 |    3                    |    2 |"
+    "|      |    3                    |    2 |"
+    "|      |    3                    |      |"
+    "+------+-------------------------+------+"
+);
+
+test_table!(
+    pool_table_alignment_right_per_line,
+    PoolTable::new([
+        ["1                     ", "2\n2       ", "3\n3\n3"],
+        ["3\n3\n3", "2\n2", "1"],
+        ["1", "3\n3\n3                   ", "2\n2"]
+    ])
+    .with(Alignment::right())
+    .with(AlignmentStrategy::PerLine),
+    "+------------------------+----------+---+"
     "| 1                      |        2 | 3 |"
     "|                        | 2        | 3 |"
     "|                        |          | 3 |"
@@ -417,7 +473,7 @@ test_table!(
     ])
     .with(Alignment::center()),
     "+------------------------+----------+---+"
-    "| 1                      |    2     | 3 |"
+    "| 1                      | 2        | 3 |"
     "|                        | 2        | 3 |"
     "|                        |          | 3 |"
     "+-------------+----------+-+--------+---+"
@@ -425,12 +481,36 @@ test_table!(
     "|      3      |     2      |            |"
     "|      3      |            |            |"
     "+------+------+------------+-----+------+"
-    "|  1   |            3            |  2   |"
-    "|      |            3            |  2   |"
+    "|  1   |  3                      |  2   |"
+    "|      |  3                      |  2   |"
     "|      |  3                      |      |"
     "+------+-------------------------+------+"
 );
 
+test_table!(
+    pool_table_alignment_center_horizontal_line_strategy,
+    PoolTable::new([
+        ["1                     ", "2\n22222", "3\n3\n3"],
+        ["3\n3\n3", "2\n2", "1"],
+        ["1", "3\n3\n3                   ", "2\n2"]
+    ])
+    .with(Alignment::center())
+    .with(AlignmentStrategy::PerLine),
+    "+------------------------+-------+---+"
+    "| 1                      |   2   | 3 |"
+    "|                        | 22222 | 3 |"
+    "|                        |       | 3 |"
+    "+------------+-----------+-------+---+"
+    "|     3      |     2     |     1     |"
+    "|     3      |     2     |           |"
+    "|     3      |           |           |"
+    "+-----+------+-----------+-----+-----+"
+    "|  1  |           3            |  2  |"
+    "|     |           3            |  2  |"
+    "|     |  3                     |     |"
+    "+-----+------------------------+-----+"
+);
+
 test_table!(
     pool_table_style_empty,
     PoolTable::new(create_matrix::<3, 3>()).with(Style::empty()),
@@ -445,7 +525,6 @@ test_table!(
     "| 0-0 | 0-1 | 0-2 |"
     "| 1-0 | 1-1 | 1-2 |"
     "| 2-0 | 2-1 | 2-2 |"
-    "|----- ----- -----|"
 );
 
 test_table!(
@@ -457,7 +536,7 @@ test_table!(
     "│ 1-0 │ 1-1 │ 1-2 │"
     " ───── ───── ───── "
     "│ 2-0 │ 2-1 │ 2-2 │"
-    "├─────┴─────┴─────┤"
+    "╰─────┴─────┴─────╯"
 );
 
 test_table!(
@@ -507,3 +586,49 @@ test_table!(
     "|      | 3                       |      |"
     "+------+-------------------------+------+"
 );
+
+test_table!(
+    pool_table_2_columns_1_cell,
+    PoolTable::from(TableValue::Row(vec![
+        TableValue::Column(vec![
+            TableValue::Cell(String::from("0-0")),
+            TableValue::Cell(String::from("0-1")),
+            TableValue::Cell(String::from("0-2")),
+            TableValue::Cell(String::from("0-3")),
+            TableValue::Cell(String::from("0-4")),
+            TableValue::Cell(String::from("0-5")),
+        ]),
+        TableValue::Column(vec![
+            TableValue::Cell(String::from("1-0")),
+            TableValue::Cell(String::from("1-1")),
+            TableValue::Cell(String::from("1-2")),
+            TableValue::Cell(String::from("1-3")),
+            TableValue::Cell(String::from("1-4")),
+            TableValue::Cell(String::from("1-6")),
+            TableValue::Cell(String::from("1-7")),
+            TableValue::Cell(String::from("1-8")),
+            TableValue::Cell(String::from("1-9")),
+        ]),
+        TableValue::Cell(String::from("2-0")),
+    ]))
+    .with(PoolTableDimension::new(DimensionPriority::Last, DimensionPriority::Last)),
+    "+-----+-----+-----+"
+    "| 0-0 | 1-0 | 2-0 |"
+    "+-----+-----+     |"
+    "| 0-1 | 1-1 |     |"
+    "+-----+-----+     |"
+    "| 0-2 | 1-2 |     |"
+    "+-----+-----+     |"
+    "| 0-3 | 1-3 |     |"
+    "+-----+-----+     |"
+    "| 0-4 | 1-4 |     |"
+    "+-----+-----+     |"
+    "| 0-5 | 1-6 |     |"
+    "|     +-----+     |"
+    "|     | 1-7 |     |"
+    "|     +-----+     |"
+    "|     | 1-8 |     |"
+    "|     +-----+     |"
+    "|     | 1-9 |     |"
+    "+-----+-----+-----+"
+);
diff --git a/tabled/tests/render_settings.rs b/tabled/tests/render_settings.rs
index 349b7e0..4d32f68 100644
--- a/tabled/tests/render_settings.rs
+++ b/tabled/tests/render_settings.rs
@@ -36,10 +36,9 @@ test_table!(
     alignment_per_line_with_trim_0,
     new_table(multiline_data1())
         .with(Style::psql())
-        .with(Modify::new(Segment::all())
-            .with(Alignment::right())
-            .with(AlignmentStrategy::PerLine)
-            .with(TrimStrategy::Horizontal)),
+        .with(Alignment::right())
+        .with(AlignmentStrategy::PerLine)
+        .with(TrimStrategy::Horizontal),
     "         N | column 0 | column 1 | column 2 "
     "-----------+----------+----------+----------"
     "         0 |      0-0 |      0-1 |      0-2 "