Repository: zhiburt/tabled (language: rust)

Issue:
Switch Symbol from String to Cow
The idea that someone could keep his styles statically so we could reduce allocations size.


Discussion / hints:
Hi, I would like to try this. Can you explain more on how do I start? and what should I do?
Yes.... the descriptions is something which often lacking....

Hi @jk-gan

So the title is a bit outdated.
But the idea is just to change these `prefix` and `suffix` to `Cow` if possible.

https://github.com/zhiburt/tabled/blob/308cdca66ad2dac07f83ab3eba9e289819d5782c/papergrid/src/color/ansi_color.rs#L6-L10


I was looking through some old `good first issue` issues and found that this seems to have been solved, I think. At least the `AnsiColor` struct now uses `Cow` instead of `String`. Should this be closed now, or are there other places you would like to use `Cow` as well?
I think it's covered,
But funnily, after some thinking, maybe it need to be reverted :)
At least to save a little memory. Cause we have a `StaticColor` as a `&str` backed.

Sooooo
there's a bit of work with `color`s.

1. It'd be nice to copy the `const`s to the `StaticColor`. (it also missing some more `BLINKING`, `ITALIC`)
2. Implement `CellOption` && `TableOption` for it.
3. Rephrase the comment  `/// Notice that the colors are constants so you can't combine them.` to `... at const time`.
4. Revert this (see above)
5. Maybe rename `StaticColor` to `Color` and `AnsiColor` to `ColorBuf`? (naming always hard, I like it but we have a `Color` trait already .... the idea it be similar to `Path` and `PathBuf`) (Hmmm I like it a lot we can rename `Color` trait to `AnsiColor` which makes sense according to methods).
6. After `4.` tabled::settings::Color shall be adjusted.

https://github.com/zhiburt/tabled/blob/74fcf7ade12d3ba5f461f67536f1a32245ef2192/tabled/src/settings/color/mod.rs#L46-L175

In case you'd like to tackle it, let me know, and probably it shall be moved to another issue.

Take care


Fix patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f3b74eef..fdee55ee 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,13 +21,13 @@ jobs:
           [
             "",
             "std",
-            "color",
+            "ansi",
             "derive",
             "macros",
-            "color,derive",
-            "color,macros",
+            "ansi,derive",
+            "ansi,macros",
             "macros,derive",
-            "color,derive,macros",
+            "ansi,derive,macros",
           ]
     runs-on: ${{ matrix.os }}
     steps:
@@ -44,7 +44,7 @@ jobs:
       matrix:
         rust: [stable]
         os: [ubuntu-latest]
-        features: ["", "std", "color", "std,color"]
+        features: ["", "std", "ansi", "std,ansi"]
     runs-on: ${{ matrix.os }}
     steps:
       - uses: actions/checkout@v3
@@ -60,7 +60,7 @@ jobs:
       matrix:
         rust: [stable]
         os: [ubuntu-latest]
-        features: ["", "color"]
+        features: ["", "ansi"]
     runs-on: ${{ matrix.os }}
     steps:
       - uses: actions/checkout@v3
@@ -76,7 +76,7 @@ jobs:
       matrix:
         rust: [stable]
         os: [ubuntu-latest]
-        features: ["", "color"]
+        features: ["", "ansi"]
     runs-on: ${{ matrix.os }}
     steps:
       - uses: actions/checkout@v3
@@ -139,7 +139,7 @@ jobs:
     strategy:
       matrix:
         target: [x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl]
-        features: ["", "std", "color"]
+        features: ["", "std", "ansi"]
     steps:
       - uses: actions/checkout@v3
       - uses: dtolnay/rust-toolchain@stable
@@ -164,7 +164,7 @@ jobs:
     strategy:
       matrix:
         target: [x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl]
-        features: ["", "color"]
+        features: ["", "ansi"]
     steps:
       - uses: actions/checkout@v3
       - uses: dtolnay/rust-toolchain@stable
diff --git a/README.md b/README.md
index 4f59d9e7..22fdd96f 100644
--- a/README.md
+++ b/README.md
@@ -1573,7 +1573,7 @@ The library doesn't bind you in usage of any color library but to be able to wor
 because of embedded ansi sequences, you should add the `color` feature of `tabled` to your `Cargo.toml`:
 
 ```toml
-tabled = { version = "*", features = ["color"] } 
+tabled = { version = "*", features = ["ansi"] } 
 ```
 
 Then you can use colored strings as values and table dimension will be properly estimated.
@@ -1961,7 +1961,7 @@ By default such things as hyperlinks, blinking and others things which can be ac
 To enable this support, add the `color` feature to your `Cargo.toml`
 
 ```toml
-tabled = { version = "*", features = ["color"] }
+tabled = { version = "*", features = ["ansi"] }
 ```
 
 ### Emoji
diff --git a/csv_to_table/Cargo.toml b/csv_to_table/Cargo.toml
index 8314e56c..877ad149 100644
--- a/csv_to_table/Cargo.toml
+++ b/csv_to_table/Cargo.toml
@@ -13,11 +13,13 @@ description = "A library for pretty print CSV as a table"
 license = "MIT"
 
 [features]
-color = ["tabled/color"]
+ansi = ["tabled/ansi"]
+derive = ["tabled/derive"]
+macros = ["tabled/macros"]
 
 [dependencies]
 csv = "1"
 tabled = { path = "../tabled", features = ["std"], default-features = false }
 
 [dev-dependencies]
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
diff --git a/json_to_table/Cargo.toml b/json_to_table/Cargo.toml
index e72094c1..3a4d1408 100644
--- a/json_to_table/Cargo.toml
+++ b/json_to_table/Cargo.toml
@@ -13,11 +13,13 @@ description = "A library for pretty print JSON as a table"
 license = "MIT"
 
 [features]
-color = ["tabled/color"]
+ansi = ["tabled/ansi"]
+derive = ["tabled/derive"]
+macros = ["tabled/macros"]
 
 [dependencies]
 serde_json = "1"
 tabled = { path = "../tabled", features = ["macros"], default-features = false }
 
 [dev-dependencies]
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
diff --git a/json_to_table/src/table/collapsed_table.rs b/json_to_table/src/table/collapsed_table.rs
index d6c904b9..286d07c3 100644
--- a/json_to_table/src/table/collapsed_table.rs
+++ b/json_to_table/src/table/collapsed_table.rs
@@ -588,7 +588,7 @@ fn generate_value_cell(value: &str, cfg: &Config, ctx: PrintContext) -> CellData
 
 struct NoTopBorders;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for NoTopBorders {
+impl<R, D> TableOption<R, ColoredConfig, D> for NoTopBorders {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top = None;
@@ -602,7 +602,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoTopBorders {
 
 struct NoBottomBorders;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for NoBottomBorders {
+impl<R, D> TableOption<R, ColoredConfig, D> for NoBottomBorders {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom = None;
@@ -616,7 +616,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoBottomBorders {
 
 struct NoRightBorders;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for NoRightBorders {
+impl<R, D> TableOption<R, ColoredConfig, D> for NoRightBorders {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_right = None;
@@ -630,7 +630,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoRightBorders {
 
 struct NoLeftBorders;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for NoLeftBorders {
+impl<R, D> TableOption<R, ColoredConfig, D> for NoLeftBorders {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = None;
@@ -644,7 +644,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for NoLeftBorders {
 
 struct TopLeftChangeTopIntersection;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeTopIntersection {
+impl<R, D> TableOption<R, ColoredConfig, D> for TopLeftChangeTopIntersection {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = borders.top_intersection;
@@ -655,7 +655,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeTopIntersection {
 
 struct TopLeftChangeIntersection;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeIntersection {
+impl<R, D> TableOption<R, ColoredConfig, D> for TopLeftChangeIntersection {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = borders.intersection;
@@ -666,7 +666,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeIntersection {
 
 struct TopLeftChangeToLeft;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeToLeft {
+impl<R, D> TableOption<R, ColoredConfig, D> for TopLeftChangeToLeft {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_left = borders.left_intersection;
@@ -677,7 +677,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeToLeft {
 
 struct TopRightChangeToRight;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for TopRightChangeToRight {
+impl<R, D> TableOption<R, ColoredConfig, D> for TopRightChangeToRight {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.top_right = borders.right_intersection;
@@ -688,7 +688,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for TopRightChangeToRight {
 
 struct BottomLeftChangeSplit;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplit {
+impl<R, D> TableOption<R, ColoredConfig, D> for BottomLeftChangeSplit {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_left = borders.left_intersection;
@@ -699,7 +699,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplit {
 
 struct BottomLeftChangeSplitToIntersection;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplitToIntersection {
+impl<R, D> TableOption<R, ColoredConfig, D> for BottomLeftChangeSplitToIntersection {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_left = borders.intersection;
@@ -710,7 +710,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplitToIntersect
 
 struct BottomRightChangeToRight;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BottomRightChangeToRight {
+impl<R, D> TableOption<R, ColoredConfig, D> for BottomRightChangeToRight {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_right = borders.right_intersection;
@@ -721,7 +721,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BottomRightChangeToRight {
 
 struct BottomLeftChangeToBottomIntersection;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeToBottomIntersection {
+impl<R, D> TableOption<R, ColoredConfig, D> for BottomLeftChangeToBottomIntersection {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let mut borders = *cfg.get_borders();
         borders.bottom_left = borders.bottom_intersection;
@@ -732,7 +732,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeToBottomIntersec
 
 struct SetBottomChars<'a>(&'a [usize], char);
 
-impl<R, D> TableOption<R, D, ColoredConfig> for SetBottomChars<'_>
+impl<R, D> TableOption<R, ColoredConfig, D> for SetBottomChars<'_>
 where
     R: Records,
     for<'a> &'a R: Records,
@@ -763,7 +763,7 @@ where
 
 struct SetTopChars<'a>(&'a [usize], char);
 
-impl<R, D> TableOption<R, D, ColoredConfig> for SetTopChars<'_> {
+impl<R, D> TableOption<R, ColoredConfig, D> for SetTopChars<'_> {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         for &split in self.0 {
             let offset = split;
@@ -774,7 +774,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<'_> {
+impl<R, D> TableOption<R, ColoredConfig, D> for SetLeftChars<'_> {
     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,7 +784,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for SetLeftChars<'_> {
 
 struct GetTopIntersection(char);
 
-impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetTopIntersection {
+impl<R, D> TableOption<R, ColoredConfig, D> for &mut GetTopIntersection {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         self.0 = cfg.get_borders().top_intersection.unwrap_or(' ');
     }
@@ -792,7 +792,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetTopIntersection {
 
 struct GetBottomIntersection(char);
 
-impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetBottomIntersection {
+impl<R, D> TableOption<R, ColoredConfig, D> 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 8bdbf644..e47ef263 100644
--- a/json_to_table/src/table/mod.rs
+++ b/json_to_table/src/table/mod.rs
@@ -311,7 +311,7 @@ impl<T> JsonTable<T> {
     /// [`Table`]: tabled::Table
     pub fn with<O>(&mut self, option: O) -> &mut Self
     where
-        O: TableOption<EmptyRecords, CompleteDimension<'static>, ColoredConfig>,
+        O: TableOption<EmptyRecords, ColoredConfig, CompleteDimension<'static>>,
     {
         let mut records = EmptyRecords::default();
         let mut dims = CompleteDimension::default();
diff --git a/papergrid/Cargo.toml b/papergrid/Cargo.toml
index 9699cfb4..95c141a0 100644
--- a/papergrid/Cargo.toml
+++ b/papergrid/Cargo.toml
@@ -10,7 +10,7 @@ license = "MIT"
 [features]
 default = ["std"]
 std = []
-color = ["ansi-str", "ansitok"]
+ansi = ["ansi-str", "ansitok"]
 
 [dependencies]
 unicode-width = "0.1"
@@ -21,11 +21,11 @@ ansitok = { version = "0.2", optional = true  }
 
 [dev-dependencies]
 owo-colors = "3.4.0"
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
 
 [[example]]
 name = "papergrid_color"
-required-features = ["std", "color"]
+required-features = ["std", "ansi"]
 
 [[example]]
 name = "color_map"
diff --git a/papergrid/examples/color_map.rs b/papergrid/examples/color_map.rs
index 94292512..2058d475 100644
--- a/papergrid/examples/color_map.rs
+++ b/papergrid/examples/color_map.rs
@@ -17,7 +17,7 @@ use owo_colors::{
 };
 
 use papergrid::{
-    color::Color,
+    ansi::ANSIFmt,
     config::spanned::SpannedConfig,
     config::{Borders, Position},
     dimension::spanned::SpannedGridDimension,
@@ -69,18 +69,17 @@ fn generate_table_config() -> SpannedConfig {
 #[derive(Debug, Clone, Default)]
 struct Style(OStyle);
 
-impl Color for Style {
-    fn fmt_prefix<W: fmt::Write>(&self, f: &mut W) -> fmt::Result {
-        let buf = OStylePrefix(&self.0).to_string();
-        f.write_str(&buf)
-    }
-}
+impl ANSIFmt for Style {
+    fn fmt_ansi_prefix<W: fmt::Write>(&self, f: &mut W) -> fmt::Result {
+        struct Prefix<'a>(&'a OStyle);
 
-struct OStylePrefix<'a>(&'a OStyle);
+        impl Display for Prefix<'_> {
+            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+                self.0.fmt_prefix(f)
+            }
+        }
 
-impl Display for OStylePrefix<'_> {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        self.0.fmt_prefix(f)
+        f.write_fmt(format_args!("{}", Prefix(&self.0)))
     }
 }
 
diff --git a/papergrid/examples/colored_border.rs b/papergrid/examples/colored_border.rs
index ec7ff284..74594c26 100644
--- a/papergrid/examples/colored_border.rs
+++ b/papergrid/examples/colored_border.rs
@@ -7,7 +7,7 @@
 //! * [`CompactConfig`] also supports colorization when the `color` feature is enabled.
 
 use papergrid::{
-    color::AnsiColor,
+    ansi::ANSIBuf,
     colors::NoColors,
     config::spanned::SpannedConfig,
     config::{AlignmentHorizontal, AlignmentVertical, Borders, Entity::Global, Indent, Sides},
@@ -68,7 +68,7 @@ fn generate_table_config() -> SpannedConfig {
             Indent::spaced(1),
         ),
     );
-    cfg.set_border_color_global(AnsiColor::new("\u{1b}[42m".into(), "\u{1b}[0m".into()));
+    cfg.set_border_color_default(ANSIBuf::new("\u{1b}[42m", "\u{1b}[0m"));
 
     cfg
 }
diff --git a/papergrid/src/color/ansi_color.rs b/papergrid/src/ansi/ansi_buf.rs
similarity index 54%
rename from papergrid/src/color/ansi_color.rs
rename to papergrid/src/ansi/ansi_buf.rs
index 03b4d403..f8ed4f34 100644
--- a/papergrid/src/color/ansi_color.rs
+++ b/papergrid/src/ansi/ansi_buf.rs
@@ -1,35 +1,37 @@
-use std::{
-    borrow::Cow,
-    fmt::{self, Write},
-};
+use std::fmt::{self, Write};
 
-use super::{Color, StaticColor};
+use super::{ANSIFmt, ANSIStr};
 
 /// The structure represents a ANSI color by suffix and prefix.
 #[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct AnsiColor<'a> {
-    prefix: Cow<'a, str>,
-    suffix: Cow<'a, str>,
+pub struct ANSIBuf {
+    prefix: String,
+    suffix: String,
 }
 
-impl<'a> AnsiColor<'a> {
+impl ANSIBuf {
     /// Constructs a new instance with suffix and prefix.
     ///
     /// They are not checked so you should make sure you provide correct ANSI.
     /// Otherwise you may want to use [`TryFrom`].
     ///
     /// [`TryFrom`]: std::convert::TryFrom
-    pub const fn new(prefix: Cow<'a, str>, suffix: Cow<'a, str>) -> Self {
+    pub fn new<P, S>(prefix: P, suffix: S) -> Self
+    where
+        P: Into<String>,
+        S: Into<String>,
+    {
+        let prefix = prefix.into();
+        let suffix = suffix.into();
+
         Self { prefix, suffix }
     }
 
     /// Checks whether the color is not actually set.
     pub fn is_empty(&self) -> bool {
-        self.prefix == "" && self.suffix == ""
+        self.prefix.is_empty() && self.suffix.is_empty()
     }
-}
 
-impl AnsiColor<'_> {
     /// Gets a reference to a prefix.
     pub fn get_prefix(&self) -> &str {
         &self.prefix
@@ -39,20 +41,25 @@ impl AnsiColor<'_> {
     pub fn get_suffix(&self) -> &str {
         &self.suffix
     }
+
+    /// Gets a reference as a color.
+    pub fn as_ref(&self) -> ANSIStr<'_> {
+        ANSIStr::new(&self.prefix, &self.suffix)
+    }
 }
 
-impl Color for AnsiColor<'_> {
-    fn fmt_prefix<W: Write>(&self, f: &mut W) -> fmt::Result {
+impl ANSIFmt for ANSIBuf {
+    fn fmt_ansi_prefix<W: Write>(&self, f: &mut W) -> fmt::Result {
         f.write_str(&self.prefix)
     }
 
-    fn fmt_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
+    fn fmt_ansi_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
         f.write_str(&self.suffix)
     }
 }
 
-#[cfg(feature = "color")]
-impl std::convert::TryFrom<&str> for AnsiColor<'static> {
+#[cfg(feature = "ansi")]
+impl std::convert::TryFrom<&str> for ANSIBuf {
     type Error = ();
 
     fn try_from(value: &str) -> Result<Self, Self::Error> {
@@ -60,8 +67,8 @@ impl std::convert::TryFrom<&str> for AnsiColor<'static> {
     }
 }
 
-#[cfg(feature = "color")]
-impl std::convert::TryFrom<String> for AnsiColor<'static> {
+#[cfg(feature = "ansi")]
+impl std::convert::TryFrom<String> for ANSIBuf {
     type Error = ();
 
     fn try_from(value: String) -> Result<Self, Self::Error> {
@@ -69,8 +76,8 @@ impl std::convert::TryFrom<String> for AnsiColor<'static> {
     }
 }
 
-#[cfg(feature = "color")]
-fn parse_ansi_color(s: &str) -> Option<AnsiColor<'static>> {
+#[cfg(feature = "ansi")]
+fn parse_ansi_color(s: &str) -> Option<ANSIBuf> {
     let mut blocks = ansi_str::get_blocks(s);
     let block = blocks.next()?;
     let style = block.style();
@@ -78,14 +85,11 @@ fn parse_ansi_color(s: &str) -> Option<AnsiColor<'static>> {
     let start = style.start().to_string();
     let end = style.end().to_string();
 
-    Some(AnsiColor::new(start.into(), end.into()))
+    Some(ANSIBuf::new(start, end))
 }
 
-impl From<StaticColor> for AnsiColor<'static> {
-    fn from(value: StaticColor) -> Self {
-        Self::new(
-            Cow::Borrowed(value.get_prefix()),
-            Cow::Borrowed(value.get_suffix()),
-        )
+impl From<ANSIStr<'_>> for ANSIBuf {
+    fn from(value: ANSIStr<'_>) -> Self {
+        Self::new(value.get_prefix(), value.get_suffix())
     }
 }
diff --git a/papergrid/src/color/static_color.rs b/papergrid/src/ansi/ansi_str.rs
similarity index 64%
rename from papergrid/src/color/static_color.rs
rename to papergrid/src/ansi/ansi_str.rs
index a53eadc7..58b32d42 100644
--- a/papergrid/src/color/static_color.rs
+++ b/papergrid/src/ansi/ansi_str.rs
@@ -1,22 +1,22 @@
 use core::fmt::{self, Write};
 
-use super::Color;
+use super::ANSIFmt;
 
 /// The structure represents a ANSI color by suffix and prefix.
 #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
-pub struct StaticColor {
-    prefix: &'static str,
-    suffix: &'static str,
+pub struct ANSIStr<'a> {
+    prefix: &'a str,
+    suffix: &'a str,
 }
 
-impl StaticColor {
+impl<'a> ANSIStr<'a> {
     /// Constructs a new instance with suffix and prefix.
     ///
     /// They are not checked so you should make sure you provide correct ANSI.
     /// Otherwise you may want to use [`TryFrom`].
     ///
     /// [`TryFrom`]: std::convert::TryFrom
-    pub const fn new(prefix: &'static str, suffix: &'static str) -> Self {
+    pub const fn new(prefix: &'a str, suffix: &'a str) -> Self {
         Self { prefix, suffix }
     }
 
@@ -24,26 +24,24 @@ impl StaticColor {
     pub const fn is_empty(&self) -> bool {
         self.prefix.is_empty() && self.suffix.is_empty()
     }
-}
 
-impl StaticColor {
     /// Gets a reference to a prefix.
-    pub fn get_prefix(&self) -> &'static str {
+    pub fn get_prefix(&self) -> &'a str {
         self.prefix
     }
 
     /// Gets a reference to a suffix.
-    pub fn get_suffix(&self) -> &'static str {
+    pub fn get_suffix(&self) -> &'a str {
         self.suffix
     }
 }
 
-impl Color for StaticColor {
-    fn fmt_prefix<W: Write>(&self, f: &mut W) -> fmt::Result {
+impl ANSIFmt for ANSIStr<'_> {
+    fn fmt_ansi_prefix<W: Write>(&self, f: &mut W) -> fmt::Result {
         f.write_str(self.prefix)
     }
 
-    fn fmt_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
+    fn fmt_ansi_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
         f.write_str(self.suffix)
     }
 }
diff --git a/papergrid/src/ansi/mod.rs b/papergrid/src/ansi/mod.rs
new file mode 100644
index 00000000..01e78433
--- /dev/null
+++ b/papergrid/src/ansi/mod.rs
@@ -0,0 +1,36 @@
+//! A module which contains [`Color`] trait and its implementation [`AnsiColor`].
+
+#[cfg(feature = "std")]
+mod ansi_buf;
+mod ansi_str;
+
+#[cfg(feature = "std")]
+pub use ansi_buf::ANSIBuf;
+
+pub use self::ansi_str::ANSIStr;
+
+use core::fmt::{self, Write};
+
+/// A trait which prints an ANSI prefix and suffix.
+pub trait ANSIFmt {
+    /// Print ANSI prefix.
+    fn fmt_ansi_prefix<W: Write>(&self, f: &mut W) -> fmt::Result;
+
+    /// Print ANSI suffix.
+    fn fmt_ansi_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
+        f.write_str("\u{1b}[0m")
+    }
+}
+
+impl<C> ANSIFmt for &C
+where
+    C: ANSIFmt,
+{
+    fn fmt_ansi_prefix<W: Write>(&self, f: &mut W) -> fmt::Result {
+        C::fmt_ansi_prefix(self, f)
+    }
+
+    fn fmt_ansi_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
+        C::fmt_ansi_suffix(self, f)
+    }
+}
diff --git a/papergrid/src/color/mod.rs b/papergrid/src/color/mod.rs
deleted file mode 100644
index e4618b75..00000000
--- a/papergrid/src/color/mod.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-//! A module which contains [`Color`] trait and its implementation [`AnsiColor`].
-
-#[cfg(feature = "std")]
-mod ansi_color;
-mod static_color;
-
-#[cfg(feature = "std")]
-pub use ansi_color::AnsiColor;
-
-pub use static_color::StaticColor;
-
-use core::fmt::{self, Write};
-
-#[allow(unreachable_pub)]
-/// A trait which prints an ANSI prefix and suffix.
-pub trait Color {
-    /// Print ANSI prefix.
-    fn fmt_prefix<W: Write>(&self, f: &mut W) -> fmt::Result;
-
-    /// Print ANSI suffix.
-    fn fmt_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
-        f.write_str("\u{1b}[0m")
-    }
-
-    /// Print colored text.
-    ///
-    /// It may not handle `\n` (new lines).
-    fn colorize<W: Write>(&self, f: &mut W, text: &str) -> fmt::Result {
-        self.fmt_prefix(f)?;
-        f.write_str(text)?;
-        self.fmt_suffix(f)?;
-        Ok(())
-    }
-}
-
-impl<C> Color for &C
-where
-    C: Color,
-{
-    fn fmt_prefix<W: Write>(&self, f: &mut W) -> fmt::Result {
-        C::fmt_prefix(self, f)
-    }
-
-    fn fmt_suffix<W: Write>(&self, f: &mut W) -> fmt::Result {
-        C::fmt_suffix(self, f)
-    }
-
-    fn colorize<W: Write>(&self, f: &mut W, text: &str) -> fmt::Result {
-        C::colorize(self, f, text)
-    }
-}
diff --git a/papergrid/src/colors.rs b/papergrid/src/colors.rs
index 10cca28a..aabcb8b7 100644
--- a/papergrid/src/colors.rs
+++ b/papergrid/src/colors.rs
@@ -1,11 +1,11 @@
 //! A module which contains [Colors] trait and its blanket implementations.
 
-use crate::{color::Color, config::Position};
+use crate::{ansi::ANSIFmt, config::Position};
 
 /// A trait which represents map of colors.
 pub trait Colors {
     /// Color implementation.
-    type Color: Color;
+    type Color: ANSIFmt;
 
     /// Returns a color for a given position.
     fn get_color(&self, pos: (usize, usize)) -> Option<&Self::Color>;
@@ -32,7 +32,7 @@ where
 #[cfg(feature = "std")]
 impl<C> Colors for std::collections::HashMap<Position, C>
 where
-    C: Color,
+    C: ANSIFmt,
 {
     type Color = C;
 
@@ -48,7 +48,7 @@ where
 #[cfg(feature = "std")]
 impl<C> Colors for std::collections::BTreeMap<Position, C>
 where
-    C: Color,
+    C: ANSIFmt,
 {
     type Color = C;
 
@@ -64,7 +64,7 @@ where
 #[cfg(feature = "std")]
 impl<C> Colors for crate::config::spanned::EntityMap<Option<C>>
 where
-    C: Color,
+    C: ANSIFmt,
 {
     type Color = C;
 
@@ -98,16 +98,12 @@ impl Colors for NoColors {
 #[derive(Debug)]
 pub struct EmptyColor;
 
-impl Color for EmptyColor {
-    fn fmt_prefix<W: core::fmt::Write>(&self, _: &mut W) -> core::fmt::Result {
+impl ANSIFmt for EmptyColor {
+    fn fmt_ansi_prefix<W: core::fmt::Write>(&self, _: &mut W) -> core::fmt::Result {
         Ok(())
     }
 
-    fn colorize<W: core::fmt::Write>(&self, _: &mut W, _: &str) -> core::fmt::Result {
-        Ok(())
-    }
-
-    fn fmt_suffix<W: core::fmt::Write>(&self, _: &mut W) -> core::fmt::Result {
+    fn fmt_ansi_suffix<W: core::fmt::Write>(&self, _: &mut W) -> core::fmt::Result {
         Ok(())
     }
 }
diff --git a/papergrid/src/config/borders.rs b/papergrid/src/config/borders.rs
index acf8fbcd..ef369eda 100644
--- a/papergrid/src/config/borders.rs
+++ b/papergrid/src/config/borders.rs
@@ -149,4 +149,28 @@ impl<T> Borders<T> {
             || self.top_intersection.is_some()
             || self.bottom_intersection.is_some()
     }
+
+    /// Converts borders type into another one.
+    pub fn convert_into<T1>(self) -> Borders<T1>
+    where
+        T1: From<T>,
+    {
+        Borders {
+            left: self.left.map(Into::into),
+            right: self.right.map(Into::into),
+            top: self.top.map(Into::into),
+            bottom: self.bottom.map(Into::into),
+            bottom_intersection: self.bottom_intersection.map(Into::into),
+            bottom_left: self.bottom_left.map(Into::into),
+            bottom_right: self.bottom_right.map(Into::into),
+            horizontal: self.horizontal.map(Into::into),
+            intersection: self.intersection.map(Into::into),
+            left_intersection: self.left_intersection.map(Into::into),
+            right_intersection: self.right_intersection.map(Into::into),
+            top_intersection: self.top_intersection.map(Into::into),
+            top_left: self.top_left.map(Into::into),
+            top_right: self.top_right.map(Into::into),
+            vertical: self.vertical.map(Into::into),
+        }
+    }
 }
diff --git a/papergrid/src/config/compact/mod.rs b/papergrid/src/config/compact/mod.rs
index ff6b9b70..4ed8e9a2 100644
--- a/papergrid/src/config/compact/mod.rs
+++ b/papergrid/src/config/compact/mod.rs
@@ -2,7 +2,7 @@
 //!
 //! [`CompactGrid`]: crate::grid::compact::CompactGrid
 
-use crate::color::StaticColor;
+use crate::ansi::ANSIStr;
 use crate::config::{AlignmentHorizontal, Borders, Indent, Sides};
 
 /// This structure represents a settings of a grid.
@@ -11,11 +11,11 @@ use crate::config::{AlignmentHorizontal, Borders, Indent, Sides};
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub struct CompactConfig {
     borders: Borders<char>,
-    border_colors: Borders<StaticColor>,
+    border_colors: Borders<ANSIStr<'static>>,
     margin: Sides<Indent>,
-    margin_color: Sides<StaticColor>,
+    margin_color: Sides<ANSIStr<'static>>,
     padding: Sides<Indent>,
-    padding_color: Sides<StaticColor>,
+    padding_color: Sides<ANSIStr<'static>>,
     halignment: AlignmentHorizontal,
 }
 
@@ -33,14 +33,14 @@ impl CompactConfig {
             borders: Borders::empty(),
             border_colors: Borders::empty(),
             margin: Sides::filled(Indent::zero()),
-            margin_color: Sides::filled(StaticColor::new("", "")),
+            margin_color: Sides::filled(ANSIStr::new("", "")),
             padding: Sides::new(
                 Indent::spaced(1),
                 Indent::spaced(1),
                 Indent::zero(),
                 Indent::zero(),
             ),
-            padding_color: Sides::filled(StaticColor::new("", "")),
+            padding_color: Sides::filled(ANSIStr::new("", "")),
         }
     }
 
@@ -67,7 +67,7 @@ impl CompactConfig {
     }
 
     /// Returns a current [`Borders`] structure.
-    pub const fn get_borders_color(&self) -> &Borders<StaticColor> {
+    pub const fn get_borders_color(&self) -> &Borders<ANSIStr<'static>> {
         &self.border_colors
     }
 
@@ -94,30 +94,30 @@ impl CompactConfig {
     }
 
     /// Sets colors of border carcass on the grid.
-    pub const fn set_borders_color(mut self, borders: Borders<StaticColor>) -> Self {
+    pub const fn set_borders_color(mut self, borders: Borders<ANSIStr<'static>>) -> Self {
         self.border_colors = borders;
         self
     }
 
     /// Set colors for a margin.
-    pub const fn set_margin_color(mut self, color: Sides<StaticColor>) -> Self {
+    pub const fn set_margin_color(mut self, color: Sides<ANSIStr<'static>>) -> Self {
         self.margin_color = color;
         self
     }
 
     /// Returns a margin color.
-    pub const fn get_margin_color(&self) -> &Sides<StaticColor> {
+    pub const fn get_margin_color(&self) -> &Sides<ANSIStr<'static>> {
         &self.margin_color
     }
 
     /// Set a padding to a given cells.
-    pub const fn set_padding_color(mut self, color: Sides<StaticColor>) -> Self {
+    pub const fn set_padding_color(mut self, color: Sides<ANSIStr<'static>>) -> Self {
         self.padding_color = color;
         self
     }
 
     /// Set a padding to a given cells.
-    pub const fn get_padding_color(&self) -> &Sides<StaticColor> {
+    pub const fn get_padding_color(&self) -> &Sides<ANSIStr<'static>> {
         &self.padding_color
     }
 }
diff --git a/papergrid/src/config/spanned/mod.rs b/papergrid/src/config/spanned/mod.rs
index 0a67183c..2266a8b9 100644
--- a/papergrid/src/config/spanned/mod.rs
+++ b/papergrid/src/config/spanned/mod.rs
@@ -8,7 +8,7 @@ mod offset;
 
 use std::collections::HashMap;
 
-use crate::color::{AnsiColor, StaticColor};
+use crate::ansi::{ANSIBuf, ANSIStr};
 use crate::config::compact::CompactConfig;
 use crate::config::Formatting;
 use crate::config::{
@@ -37,14 +37,14 @@ pub struct SpannedConfig {
     span_columns: HashMap<Position, usize>,
     span_rows: HashMap<Position, usize>,
     borders: BordersConfig<char>,
-    borders_colors: BordersConfig<AnsiColor<'static>>,
+    borders_colors: BordersConfig<ANSIBuf>,
     borders_missing_char: char,
     horizontal_chars: HashMap<Position, HashMap<Offset, char>>,
-    horizontal_colors: HashMap<Position, HashMap<Offset, AnsiColor<'static>>>, // squash a map to be HashMap<(Pos, Offset), char>
+    horizontal_colors: HashMap<Position, HashMap<Offset, ANSIBuf>>, // squash a map to be HashMap<(Pos, Offset), char>
     vertical_chars: HashMap<Position, HashMap<Offset, char>>,
-    vertical_colors: HashMap<Position, HashMap<Offset, AnsiColor<'static>>>,
+    vertical_colors: HashMap<Position, HashMap<Offset, ANSIBuf>>,
     justification: EntityMap<char>,
-    justification_color: EntityMap<Option<AnsiColor<'static>>>,
+    justification_color: EntityMap<Option<ANSIBuf>>,
 }
 
 impl Default for SpannedConfig {
@@ -80,7 +80,7 @@ impl SpannedConfig {
     }
 
     /// Set a color of margin of a grid.
-    pub fn set_margin_color(&mut self, margin: Sides<Option<AnsiColor<'static>>>) {
+    pub fn set_margin_color(&mut self, margin: Sides<Option<ANSIBuf>>) {
         self.margin.left.color = margin.left;
         self.margin.right.color = margin.right;
         self.margin.top.color = margin.top;
@@ -106,7 +106,7 @@ impl SpannedConfig {
     }
 
     /// Returns a margin color value currently set.
-    pub fn get_margin_color(&self) -> Sides<Option<AnsiColor<'static>>> {
+    pub fn get_margin_color(&self) -> Sides<Option<ANSIBuf>> {
         Sides::new(
             self.margin.left.color.clone(),
             self.margin.right.color.clone(),
@@ -161,12 +161,12 @@ impl SpannedConfig {
     }
 
     /// Gets a global border value if set.
-    pub fn get_global_border(&self) -> Option<&char> {
+    pub fn get_border_default(&self) -> Option<&char> {
         self.borders.get_global()
     }
 
     /// Set the all [`Borders`] values to a char.
-    pub fn set_global_border(&mut self, c: char) {
+    pub fn set_border_default(&mut self, c: char) {
         self.borders.set_global(c);
     }
 
@@ -348,7 +348,7 @@ impl SpannedConfig {
     }
 
     /// Override a character color on a horizontal line.
-    pub fn set_horizontal_color(&mut self, pos: Position, c: AnsiColor<'static>, offset: Offset) {
+    pub fn set_horizontal_color(&mut self, pos: Position, c: ANSIBuf, offset: Offset) {
         let chars = self
             .horizontal_colors
             .entry(pos)
@@ -363,7 +363,7 @@ impl SpannedConfig {
         pos: Position,
         offset: usize,
         end: usize,
-    ) -> Option<&AnsiColor<'static>> {
+    ) -> Option<&ANSIBuf> {
         self.horizontal_colors.get(&pos).and_then(|chars| {
             chars.get(&Offset::Begin(offset)).or_else(|| {
                 if end > offset {
@@ -380,7 +380,7 @@ impl SpannedConfig {
     }
 
     /// Override a character color on a vertical line.
-    pub fn set_vertical_color(&mut self, pos: Position, c: AnsiColor<'static>, offset: Offset) {
+    pub fn set_vertical_color(&mut self, pos: Position, c: ANSIBuf, offset: Offset) {
         let chars = self
             .vertical_colors
             .entry(pos)
@@ -395,7 +395,7 @@ impl SpannedConfig {
         pos: Position,
         offset: usize,
         end: usize,
-    ) -> Option<&AnsiColor<'static>> {
+    ) -> Option<&ANSIBuf> {
         self.vertical_colors.get(&pos).and_then(|chars| {
             chars.get(&Offset::Begin(offset)).or_else(|| {
                 if end > offset {
@@ -423,11 +423,7 @@ impl SpannedConfig {
     }
 
     /// Set a padding to a given cells.
-    pub fn set_padding_color(
-        &mut self,
-        entity: Entity,
-        padding: Sides<Option<AnsiColor<'static>>>,
-    ) {
+    pub fn set_padding_color(&mut self, entity: Entity, padding: Sides<Option<ANSIBuf>>) {
         let mut pad = self.padding.get(entity).clone();
         pad.left.color = padding.left;
         pad.right.color = padding.right;
@@ -449,7 +445,7 @@ impl SpannedConfig {
     }
 
     /// Get a padding color for a given [Entity].
-    pub fn get_padding_color(&self, entity: Entity) -> Sides<Option<AnsiColor<'static>>> {
+    pub fn get_padding_color(&self, entity: Entity) -> Sides<Option<ANSIBuf>> {
         let pad = self.padding.get(entity);
         Sides::new(
             pad.left.color.clone(),
@@ -500,11 +496,7 @@ impl SpannedConfig {
     }
 
     /// Returns a border color of a cell.
-    pub fn get_border_color(
-        &self,
-        pos: Position,
-        shape: (usize, usize),
-    ) -> Border<&AnsiColor<'static>> {
+    pub fn get_border_color(&self, pos: Position, shape: (usize, usize)) -> Border<&ANSIBuf> {
         self.borders_colors.get_border(pos, shape)
     }
 
@@ -521,30 +513,28 @@ impl SpannedConfig {
     }
 
     /// Gets a color of all borders on the grid.
-    pub fn get_border_color_global(&self) -> Option<&AnsiColor<'static>> {
+    pub fn get_border_color_default(&self) -> Option<&ANSIBuf> {
         self.borders_colors.get_global()
     }
 
     /// Sets a color of all borders on the grid.
-    pub fn set_border_color_global(&mut self, clr: AnsiColor<'static>) {
-        // todo: change this _global to insert by Entity
-
+    pub fn set_border_color_default(&mut self, clr: ANSIBuf) {
         self.borders_colors = BordersConfig::default();
         self.borders_colors.set_global(clr);
     }
 
     /// Gets colors of a borders carcass on the grid.
-    pub fn get_color_borders(&self) -> &Borders<AnsiColor<'static>> {
+    pub fn get_color_borders(&self) -> &Borders<ANSIBuf> {
         self.borders_colors.get_borders()
     }
 
     /// Sets colors of border carcass on the grid.
-    pub fn set_borders_color(&mut self, clrs: Borders<AnsiColor<'static>>) {
+    pub fn set_borders_color(&mut self, clrs: Borders<ANSIBuf>) {
         self.borders_colors.set_borders(clrs);
     }
 
     /// Sets a color of border of a cell on the grid.
-    pub fn set_border_color(&mut self, pos: Position, border: Border<AnsiColor<'static>>) {
+    pub fn set_border_color(&mut self, pos: Position, border: Border<ANSIBuf>) {
         self.borders_colors.insert_border(pos, border)
     }
 
@@ -572,7 +562,7 @@ impl SpannedConfig {
     /// Get a justification color which will be used while expanding cells width/height.
     ///
     /// `None` means no color.
-    pub fn get_justification_color(&self, entity: Entity) -> Option<&AnsiColor<'static>> {
+    pub fn get_justification_color(&self, entity: Entity) -> Option<&ANSIBuf> {
         self.justification_color.get(entity).as_ref()
     }
 
@@ -584,7 +574,7 @@ impl SpannedConfig {
     /// Set a justification color which will be used while expanding cells width/height.
     ///
     /// `None` removes it.
-    pub fn set_justification_color(&mut self, entity: Entity, color: Option<AnsiColor<'static>>) {
+    pub fn set_justification_color(&mut self, entity: Entity, color: Option<ANSIBuf>) {
         self.justification_color.insert(entity, color);
     }
 
@@ -753,29 +743,17 @@ impl SpannedConfig {
     }
 
     /// Gets a color of a cell horizontal.
-    pub fn get_horizontal_color(
-        &self,
-        pos: Position,
-        count_rows: usize,
-    ) -> Option<&AnsiColor<'static>> {
+    pub fn get_horizontal_color(&self, pos: Position, count_rows: usize) -> Option<&ANSIBuf> {
         self.borders_colors.get_horizontal(pos, count_rows)
     }
 
     /// Gets a color of a cell vertical.
-    pub fn get_vertical_color(
-        &self,
-        pos: Position,
-        count_columns: usize,
-    ) -> Option<&AnsiColor<'static>> {
+    pub fn get_vertical_color(&self, pos: Position, count_columns: usize) -> Option<&ANSIBuf> {
         self.borders_colors.get_vertical(pos, count_columns)
     }
 
     /// Gets a color of a cell vertical.
-    pub fn get_intersection_color(
-        &self,
-        pos: Position,
-        shape: (usize, usize),
-    ) -> Option<&AnsiColor<'static>> {
+    pub fn get_intersection_color(&self, pos: Position, shape: (usize, usize)) -> Option<&ANSIBuf> {
         self.borders_colors.get_intersection(pos, shape)
     }
 
@@ -846,15 +824,13 @@ impl From<CompactConfig> for SpannedConfig {
         cfg.set_margin_color(to_ansi_color(*compact.get_margin_color()));
         cfg.set_alignment_horizontal(Global, compact.get_alignment_horizontal());
         cfg.set_borders(*compact.get_borders());
-        cfg.set_borders_color(borders_static_color_to_ansi_color(
-            *compact.get_borders_color(),
-        ));
+        cfg.set_borders_color(compact.get_borders_color().convert_into());
 
         cfg
     }
 }
 
-fn to_ansi_color(b: Sides<StaticColor>) -> Sides<Option<AnsiColor<'static>>> {
+fn to_ansi_color(b: Sides<ANSIStr<'_>>) -> Sides<Option<ANSIBuf>> {
     Sides::new(
         Some(b.left.into()),
         Some(b.right.into()),
@@ -863,26 +839,6 @@ fn to_ansi_color(b: Sides<StaticColor>) -> Sides<Option<AnsiColor<'static>>> {
     )
 }
 
-fn borders_static_color_to_ansi_color(b: Borders<StaticColor>) -> Borders<AnsiColor<'static>> {
-    Borders {
-        left: b.left.map(|c| c.into()),
-        right: b.right.map(|c| c.into()),
-        top: b.top.map(|c| c.into()),
-        bottom: b.bottom.map(|c| c.into()),
-        bottom_intersection: b.bottom_intersection.map(|c| c.into()),
-        bottom_left: b.bottom_left.map(|c| c.into()),
-        bottom_right: b.bottom_right.map(|c| c.into()),
-        horizontal: b.horizontal.map(|c| c.into()),
-        intersection: b.intersection.map(|c| c.into()),
-        left_intersection: b.left_intersection.map(|c| c.into()),
-        right_intersection: b.right_intersection.map(|c| c.into()),
-        top_intersection: b.top_intersection.map(|c| c.into()),
-        top_left: b.top_left.map(|c| c.into()),
-        top_right: b.top_right.map(|c| c.into()),
-        vertical: b.vertical.map(|c| c.into()),
-    }
-}
-
 fn set_cell_row_span(cfg: &mut SpannedConfig, pos: Position, span: usize) {
     // such spans aren't supported
     if span == 0 {
@@ -945,7 +901,7 @@ fn is_cell_covered_by_both_spans(cfg: &SpannedConfig, pos: Position) -> bool {
 #[derive(Default, Debug, Clone, PartialEq, Eq)]
 struct ColoredIndent {
     indent: Indent,
-    color: Option<AnsiColor<'static>>,
+    color: Option<ANSIBuf>,
 }
 
 /// A colorefull margin indent.
@@ -956,7 +912,7 @@ struct ColoredMarginIndent {
     /// An offset value.
     offset: Offset,
     /// An color value.
-    color: Option<AnsiColor<'static>>,
+    color: Option<ANSIBuf>,
 }
 
 impl Default for ColoredMarginIndent {
diff --git a/papergrid/src/grid/compact.rs b/papergrid/src/grid/compact.rs
index 7950e024..3b7a5c08 100644
--- a/papergrid/src/grid/compact.rs
+++ b/papergrid/src/grid/compact.rs
@@ -7,7 +7,7 @@ use core::{
 };
 
 use crate::{
-    color::{Color, StaticColor},
+    ansi::{ANSIFmt, ANSIStr},
     colors::{Colors, NoColors},
     config::{AlignmentHorizontal, Borders, HorizontalLine, Indent, Sides},
     dimension::Dimension,
@@ -279,7 +279,7 @@ fn create_margin(cfg: &CompactConfig) -> Sides<ColoredIndent> {
 
 fn create_vertical_borders(
     borders: &Borders<char>,
-    colors: &Borders<StaticColor>,
+    colors: &Borders<ANSIStr<'static>>,
 ) -> HorizontalLine<ColoredIndent> {
     let intersect = borders
         .vertical
@@ -296,7 +296,7 @@ fn print_horizontal_line<F, D>(
     f: &mut F,
     dims: &D,
     borders: &HorizontalLine<char>,
-    borders_colors: &HorizontalLine<StaticColor>,
+    borders_colors: &HorizontalLine<ANSIStr<'static>>,
     margin: &Sides<ColoredIndent>,
     count_columns: usize,
 ) -> fmt::Result
@@ -394,15 +394,17 @@ fn create_horizontal_bottom(b: &Borders<char>) -> HorizontalLine<char> {
     )
 }
 
-fn create_horizontal_colors(b: &Borders<StaticColor>) -> HorizontalLine<StaticColor> {
+fn create_horizontal_colors(b: &Borders<ANSIStr<'static>>) -> HorizontalLine<ANSIStr<'static>> {
     HorizontalLine::new(b.horizontal, b.intersection, b.left, b.right)
 }
 
-fn create_horizontal_top_colors(b: &Borders<StaticColor>) -> HorizontalLine<StaticColor> {
+fn create_horizontal_top_colors(b: &Borders<ANSIStr<'static>>) -> HorizontalLine<ANSIStr<'static>> {
     HorizontalLine::new(b.top, b.top_intersection, b.top_left, b.top_right)
 }
 
-fn create_horizontal_bottom_colors(b: &Borders<StaticColor>) -> HorizontalLine<StaticColor> {
+fn create_horizontal_bottom_colors(
+    b: &Borders<ANSIStr<'static>>,
+) -> HorizontalLine<ANSIStr<'static>> {
     HorizontalLine::new(
         b.bottom,
         b.bottom_intersection,
@@ -509,7 +511,7 @@ fn print_columns_empty_colored<F, D>(
     f: &mut F,
     dims: &D,
     borders: &HorizontalLine<ColoredIndent>,
-    color: Option<StaticColor>,
+    color: Option<ANSIStr<'static>>,
     count_columns: usize,
 ) -> fmt::Result
 where
@@ -557,7 +559,7 @@ fn print_cell<F, C>(
 ) -> fmt::Result
 where
     F: Write,
-    C: Color,
+    C: ANSIFmt,
 {
     let available = width - (padding.left.space.size + padding.right.space.size);
 
@@ -583,14 +585,14 @@ fn print_split_line_colored<F, D>(
     f: &mut F,
     dimension: &D,
     borders: &HorizontalLine<char>,
-    borders_colors: &HorizontalLine<StaticColor>,
+    borders_colors: &HorizontalLine<ANSIStr<'static>>,
     count_columns: usize,
 ) -> fmt::Result
 where
     F: Write,
     D: Dimension,
 {
-    let mut used_color = StaticColor::default();
+    let mut used_color = ANSIStr::default();
     let chars_main = borders.main.unwrap_or(' ');
 
     if let Some(c) = borders.left {
@@ -637,7 +639,7 @@ where
         f.write_char(c)?;
     }
 
-    used_color.fmt_suffix(f)?;
+    used_color.fmt_ansi_suffix(f)?;
 
     Ok(())
 }
@@ -684,13 +686,13 @@ where
 fn print_text<F, C>(f: &mut F, text: &str, color: Option<C>) -> fmt::Result
 where
     F: Write,
-    C: Color,
+    C: ANSIFmt,
 {
     match color {
         Some(color) => {
-            color.fmt_prefix(f)?;
+            color.fmt_ansi_prefix(f)?;
             f.write_str(text)?;
-            color.fmt_suffix(f)?;
+            color.fmt_ansi_suffix(f)?;
         }
         None => {
             f.write_str(text)?;
@@ -700,13 +702,17 @@ where
     Ok(())
 }
 
-fn prepare_coloring<F>(f: &mut F, clr: &StaticColor, used: &mut StaticColor) -> fmt::Result
+fn prepare_coloring<F>(
+    f: &mut F,
+    clr: &ANSIStr<'static>,
+    used: &mut ANSIStr<'static>,
+) -> fmt::Result
 where
     F: Write,
 {
     if *used != *clr {
-        used.fmt_suffix(f)?;
-        clr.fmt_prefix(f)?;
+        used.fmt_ansi_suffix(f)?;
+        clr.fmt_ansi_prefix(f)?;
         *used = *clr;
     }
 
@@ -742,15 +748,15 @@ where
 }
 
 // todo: replace Option<StaticColor> to StaticColor and check performance
-fn print_char<F>(f: &mut F, c: char, color: Option<StaticColor>) -> fmt::Result
+fn print_char<F>(f: &mut F, c: char, color: Option<ANSIStr<'static>>) -> fmt::Result
 where
     F: Write,
 {
     match color {
         Some(color) => {
-            color.fmt_prefix(f)?;
+            color.fmt_ansi_prefix(f)?;
             f.write_char(c)?;
-            color.fmt_suffix(f)
+            color.fmt_ansi_suffix(f)
         }
         None => f.write_char(c),
     }
@@ -777,9 +783,9 @@ where
 {
     match indent.color {
         Some(color) => {
-            color.fmt_prefix(f)?;
+            color.fmt_ansi_prefix(f)?;
             repeat_char(f, indent.space.fill, indent.space.size)?;
-            color.fmt_suffix(f)?;
+            color.fmt_ansi_suffix(f)?;
         }
         None => {
             repeat_char(f, indent.space.fill, indent.space.size)?;
@@ -792,18 +798,18 @@ where
 #[derive(Debug, Clone, Copy)]
 struct ColoredIndent {
     space: Indent,
-    color: Option<StaticColor>,
+    color: Option<ANSIStr<'static>>,
 }
 
 impl ColoredIndent {
-    fn new(width: usize, c: char, color: Option<StaticColor>) -> Self {
+    fn new(width: usize, c: char, color: Option<ANSIStr<'static>>) -> Self {
         Self {
             space: Indent::new(width, c),
             color,
         }
     }
 
-    fn from_indent(indent: Indent, color: StaticColor) -> Self {
+    fn from_indent(indent: Indent, color: ANSIStr<'static>) -> Self {
         Self {
             space: indent,
             color: create_color(color),
@@ -811,7 +817,7 @@ impl ColoredIndent {
     }
 }
 
-fn create_color(color: StaticColor) -> Option<StaticColor> {
+fn create_color(color: ANSIStr<'static>) -> Option<ANSIStr<'static>> {
     if color.is_empty() {
         None
     } else {
diff --git a/papergrid/src/grid/iterable.rs b/papergrid/src/grid/iterable.rs
index a940d32f..cdc07842 100644
--- a/papergrid/src/grid/iterable.rs
+++ b/papergrid/src/grid/iterable.rs
@@ -8,7 +8,7 @@ use std::{
 };
 
 use crate::{
-    color::{AnsiColor, Color},
+    ansi::{ANSIBuf, ANSIFmt},
     colors::Colors,
     config::spanned::{Offset, SpannedConfig},
     config::{AlignmentHorizontal, AlignmentVertical, Formatting, Indent, Position, Sides},
@@ -284,7 +284,7 @@ where
     Ok(())
 }
 
-fn print_single_line_column<F: Write, C: Color>(
+fn print_single_line_column<F: Write, C: ANSIFmt>(
     f: &mut F,
     text: &str,
     cfg: &SpannedConfig,
@@ -327,7 +327,7 @@ fn print_single_line_column<F: Write, C: Color>(
 }
 
 #[allow(clippy::too_many_arguments)]
-fn print_columns_lines<T, F: Write, C: Color>(
+fn print_columns_lines<T, F: Write, C: ANSIFmt>(
     f: &mut F,
     buf: &mut [Cell<T, C>],
     height: usize,
@@ -414,7 +414,7 @@ fn print_split_line<F: Write, D: Dimension>(
     }
 
     if let Some(clr) = used_color.take() {
-        clr.fmt_suffix(f)?;
+        clr.fmt_ansi_suffix(f)?;
     }
 
     Ok(())
@@ -512,7 +512,7 @@ where
     Ok(())
 }
 
-fn print_split_line_spanned<S, F: Write, D: Dimension, C: Color>(
+fn print_split_line_spanned<S, F: Write, D: Dimension, C: ANSIFmt>(
     f: &mut F,
     buf: &mut BTreeMap<usize, (Cell<S, C>, usize, usize)>,
     cfg: &SpannedConfig,
@@ -560,7 +560,7 @@ fn print_split_line_spanned<S, F: Write, D: Dimension, C: Color>(
     }
 
     if let Some(clr) = used_color.take() {
-        clr.fmt_suffix(f)?;
+        clr.fmt_ansi_suffix(f)?;
     }
 
     Ok(())
@@ -571,7 +571,7 @@ fn print_vertical_intersection<'a, F: fmt::Write>(
     cfg: &'a SpannedConfig,
     pos: Position,
     shape: (usize, usize),
-    used_color: &mut Option<&'a AnsiColor<'static>>,
+    used_color: &mut Option<&'a ANSIBuf>,
 ) -> fmt::Result {
     if !cfg.has_vertical(pos.1, shape.1) {
         return Ok(());
@@ -727,7 +727,7 @@ fn print_horizontal_border<F: Write>(
     pos: Position,
     width: usize,
     c: char,
-    used_color: &Option<&AnsiColor<'static>>,
+    used_color: &Option<&ANSIBuf>,
 ) -> fmt::Result {
     if !cfg.is_overridden_horizontal(pos) {
         return repeat_char(f, c, width);
@@ -738,16 +738,16 @@ fn print_horizontal_border<F: Write>(
         match cfg.lookup_horizontal_color(pos, i, width) {
             Some(color) => match used_color {
                 Some(clr) => {
-                    clr.fmt_suffix(f)?;
-                    color.fmt_prefix(f)?;
+                    clr.fmt_ansi_suffix(f)?;
+                    color.fmt_ansi_prefix(f)?;
                     f.write_char(c)?;
-                    color.fmt_suffix(f)?;
-                    clr.fmt_prefix(f)?;
+                    color.fmt_ansi_suffix(f)?;
+                    clr.fmt_ansi_prefix(f)?;
                 }
                 None => {
-                    color.fmt_prefix(f)?;
+                    color.fmt_ansi_prefix(f)?;
                     f.write_char(c)?;
-                    color.fmt_suffix(f)?;
+                    color.fmt_ansi_suffix(f)?;
                 }
             },
             _ => f.write_char(c)?,
@@ -765,9 +765,9 @@ struct Cell<T, C> {
     alignh: AlignmentHorizontal,
     fmt: Formatting,
     pad: Sides<Indent>,
-    pad_color: Sides<Option<AnsiColor<'static>>>,
+    pad_color: Sides<Option<ANSIBuf>>,
     color: Option<C>,
-    justification: (char, Option<AnsiColor<'static>>),
+    justification: (char, Option<ANSIBuf>),
 }
 
 impl<T, C> Cell<T, C>
@@ -830,7 +830,7 @@ where
 
 impl<T, C> Cell<T, C>
 where
-    C: Color,
+    C: ANSIFmt,
 {
     fn display<F: Write>(&mut self, f: &mut F) -> fmt::Result {
         if self.indent_top > 0 {
@@ -916,39 +916,39 @@ impl<C> LinesIter<C> {
     }
 }
 
-fn print_text<F: Write>(f: &mut F, text: &str, clr: Option<impl Color>) -> fmt::Result {
+fn print_text<F: Write>(f: &mut F, text: &str, clr: Option<impl ANSIFmt>) -> fmt::Result {
     match clr {
         Some(color) => {
-            color.fmt_prefix(f)?;
+            color.fmt_ansi_prefix(f)?;
             f.write_str(text)?;
-            color.fmt_suffix(f)
+            color.fmt_ansi_suffix(f)
         }
         None => f.write_str(text),
     }
 }
 
-fn prepare_coloring<'a, 'b, F: Write>(
+fn prepare_coloring<'a, F: Write>(
     f: &mut F,
-    clr: Option<&'a AnsiColor<'b>>,
-    used_color: &mut Option<&'a AnsiColor<'b>>,
+    clr: Option<&'a ANSIBuf>,
+    used_color: &mut Option<&'a ANSIBuf>,
 ) -> fmt::Result {
     match clr {
         Some(clr) => match used_color.as_mut() {
             Some(used_clr) => {
                 if **used_clr != *clr {
-                    used_clr.fmt_suffix(f)?;
-                    clr.fmt_prefix(f)?;
+                    used_clr.fmt_ansi_suffix(f)?;
+                    clr.fmt_ansi_prefix(f)?;
                     *used_clr = clr;
                 }
             }
             None => {
-                clr.fmt_prefix(f)?;
+                clr.fmt_ansi_prefix(f)?;
                 *used_color = Some(clr);
             }
         },
         None => {
             if let Some(clr) = used_color.take() {
-                clr.fmt_suffix(f)?
+                clr.fmt_ansi_suffix(f)?
             }
         }
     }
@@ -1024,9 +1024,9 @@ fn print_vertical_char<F: Write>(
 
     match color {
         Some(clr) => {
-            clr.fmt_prefix(f)?;
+            clr.fmt_ansi_prefix(f)?;
             f.write_char(symbol)?;
-            clr.fmt_suffix(f)?;
+            clr.fmt_ansi_suffix(f)?;
         }
         None => f.write_char(symbol)?,
     }
@@ -1080,7 +1080,7 @@ fn print_margin_vertical<F: Write>(
     f: &mut F,
     indent: Indent,
     offset: Offset,
-    color: Option<&AnsiColor<'_>>,
+    color: Option<&ANSIBuf>,
     line: usize,
     height: Option<usize>,
 ) -> fmt::Result {
@@ -1123,7 +1123,7 @@ fn print_indent_lines<F: Write>(
     f: &mut F,
     indent: &Indent,
     offset: &Offset,
-    color: Option<&AnsiColor<'_>>,
+    color: Option<&ANSIBuf>,
     width: usize,
 ) -> fmt::Result {
     if indent.size == 0 {
@@ -1160,34 +1160,29 @@ fn print_indent_lines<F: Write>(
     Ok(())
 }
 
-fn print_padding<F: Write>(f: &mut F, pad: &Indent, color: Option<&AnsiColor<'_>>) -> fmt::Result {
+fn print_padding<F: Write>(f: &mut F, pad: &Indent, color: Option<&ANSIBuf>) -> fmt::Result {
     print_indent(f, pad.fill, pad.size, color)
 }
 
 fn print_padding_n<F: Write>(
     f: &mut F,
     pad: &Indent,
-    color: Option<&AnsiColor<'_>>,
+    color: Option<&ANSIBuf>,
     n: usize,
 ) -> fmt::Result {
     print_indent(f, pad.fill, n, color)
 }
 
-fn print_indent<F: Write>(
-    f: &mut F,
-    c: char,
-    n: usize,
-    color: Option<&AnsiColor<'_>>,
-) -> fmt::Result {
+fn print_indent<F: Write>(f: &mut F, c: char, n: usize, color: Option<&ANSIBuf>) -> fmt::Result {
     if n == 0 {
         return Ok(());
     }
 
     match color {
         Some(color) => {
-            color.fmt_prefix(f)?;
+            color.fmt_ansi_prefix(f)?;
             repeat_char(f, c, n)?;
-            color.fmt_suffix(f)
+            color.fmt_ansi_suffix(f)
         }
         None => repeat_char(f, c, n),
     }
@@ -1250,12 +1245,12 @@ fn convert_count_rows(row: usize, is_last: bool) -> usize {
 
 /// Trims a string.
 fn string_trim(text: &str) -> Cow<'_, str> {
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         ansi_str::AnsiStr::ansi_trim(text)
     }
 
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         text.trim().into()
     }
@@ -1341,7 +1336,7 @@ mod tests {
     //     assert_eq!(F("🎩", AlignmentHorizontal::Center, 4).to_string(), " 🎩 ");
     //     assert_eq!(F("🎩", AlignmentHorizontal::Center, 3).to_string(), "🎩 ");
 
-    //     #[cfg(feature = "color")]
+    //     #[cfg(feature = "ansi")]
     //     {
     //         use owo_colors::OwoColorize;
     //         let text = "Colored Text".red().to_string();
diff --git a/papergrid/src/grid/peekable.rs b/papergrid/src/grid/peekable.rs
index c1bdf520..5ba26140 100644
--- a/papergrid/src/grid/peekable.rs
+++ b/papergrid/src/grid/peekable.rs
@@ -8,7 +8,7 @@ use std::{
 };
 
 use crate::{
-    color::{AnsiColor, Color},
+    ansi::{ANSIBuf, ANSIFmt},
     colors::Colors,
     config::{
         spanned::{Offset, SpannedConfig},
@@ -503,12 +503,12 @@ mod grid_basic {
 
     /// Trims a string.
     fn string_trim(text: &str) -> Cow<'_, str> {
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         {
             ansi_str::AnsiStr::ansi_trim(text)
         }
 
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         {
             text.trim().into()
         }
@@ -675,7 +675,7 @@ mod grid_not_spanned {
         }
 
         if let Some(clr) = used_color.take() {
-            clr.fmt_suffix(f)?;
+            clr.fmt_ansi_suffix(f)?;
         }
 
         Ok(())
@@ -686,7 +686,7 @@ mod grid_not_spanned {
         cfg: &'a SpannedConfig,
         pos: Position,
         shape: Shape,
-        used_color: &mut Option<&'a AnsiColor<'static>>,
+        used_color: &mut Option<&'a ANSIBuf>,
     ) -> fmt::Result
     where
         F: fmt::Write,
@@ -713,10 +713,10 @@ mod grid_not_spanned {
         Ok(())
     }
 
-    fn prepare_coloring<'a, 'b, F>(
+    fn prepare_coloring<'a, F>(
         f: &mut F,
-        clr: Option<&'a AnsiColor<'b>>,
-        used_color: &mut Option<&'a AnsiColor<'b>>,
+        clr: Option<&'a ANSIBuf>,
+        used_color: &mut Option<&'a ANSIBuf>,
     ) -> fmt::Result
     where
         F: Write,
@@ -725,19 +725,19 @@ mod grid_not_spanned {
             Some(clr) => match used_color.as_mut() {
                 Some(used_clr) => {
                     if **used_clr != *clr {
-                        used_clr.fmt_suffix(f)?;
-                        clr.fmt_prefix(f)?;
+                        used_clr.fmt_ansi_suffix(f)?;
+                        clr.fmt_ansi_prefix(f)?;
                         *used_clr = clr;
                     }
                 }
                 None => {
-                    clr.fmt_prefix(f)?;
+                    clr.fmt_ansi_prefix(f)?;
                     *used_color = Some(clr);
                 }
             },
             None => {
                 if let Some(clr) = used_color.take() {
-                    clr.fmt_suffix(f)?
+                    clr.fmt_ansi_suffix(f)?
                 }
             }
         }
@@ -771,9 +771,9 @@ mod grid_not_spanned {
 
         match color {
             Some(clr) => {
-                clr.fmt_prefix(f)?;
+                clr.fmt_ansi_prefix(f)?;
                 f.write_char(symbol)?;
-                clr.fmt_suffix(f)?;
+                clr.fmt_ansi_suffix(f)?;
             }
             None => f.write_char(symbol)?,
         }
@@ -787,7 +787,7 @@ mod grid_not_spanned {
         pos: Position,
         width: usize,
         c: char,
-        used_color: &Option<&AnsiColor<'static>>,
+        used_color: &Option<&ANSIBuf>,
     ) -> fmt::Result
     where
         F: Write,
@@ -801,16 +801,16 @@ mod grid_not_spanned {
             match cfg.lookup_horizontal_color(pos, i, width) {
                 Some(color) => match used_color {
                     Some(clr) => {
-                        clr.fmt_suffix(f)?;
-                        color.fmt_prefix(f)?;
+                        clr.fmt_ansi_suffix(f)?;
+                        color.fmt_ansi_prefix(f)?;
                         f.write_char(c)?;
-                        color.fmt_suffix(f)?;
-                        clr.fmt_prefix(f)?;
+                        color.fmt_ansi_suffix(f)?;
+                        clr.fmt_ansi_prefix(f)?;
                     }
                     None => {
-                        color.fmt_prefix(f)?;
+                        color.fmt_ansi_prefix(f)?;
                         f.write_char(c)?;
-                        color.fmt_suffix(f)?;
+                        color.fmt_ansi_suffix(f)?;
                     }
                 },
                 _ => f.write_char(c)?,
@@ -899,12 +899,12 @@ mod grid_not_spanned {
         pos: Position,
         index: usize,
         available: usize,
-        cfg: TextCfg<C, &'_ AnsiColor<'static>>,
+        cfg: TextCfg<C, &'_ ANSIBuf>,
     ) -> fmt::Result
     where
         F: Write,
         R: Records + PeekableRecords,
-        C: Color,
+        C: ANSIFmt,
     {
         let line = records.get_line(pos, index);
         let (line, line_width) = if cfg.formatting.horizontal_trim {
@@ -951,8 +951,8 @@ mod grid_not_spanned {
     ) -> fmt::Result
     where
         F: Write,
-        C: Color,
-        C1: Color,
+        C: ANSIFmt,
+        C1: ANSIFmt,
     {
         print_indent2(f, &justification, indent.left)?;
         print_text2(f, text)?;
@@ -964,13 +964,13 @@ mod grid_not_spanned {
     fn print_text2<F, C>(f: &mut F, text: Colored<&str, C>) -> fmt::Result
     where
         F: Write,
-        C: Color,
+        C: ANSIFmt,
     {
         match text.color {
             Some(color) => {
-                color.fmt_prefix(f)?;
+                color.fmt_ansi_prefix(f)?;
                 f.write_str(text.data)?;
-                color.fmt_suffix(f)
+                color.fmt_ansi_suffix(f)
             }
             None => f.write_str(text.data),
         }
@@ -1122,7 +1122,7 @@ mod grid_not_spanned {
         f: &mut F,
         indent: Indent,
         offset: Offset,
-        color: Option<&AnsiColor<'_>>,
+        color: Option<&ANSIBuf>,
         line: usize,
         height: usize,
     ) -> fmt::Result
@@ -1161,7 +1161,7 @@ mod grid_not_spanned {
         f: &mut F,
         indent: Indent,
         offset: Offset,
-        color: Option<&AnsiColor<'_>>,
+        color: Option<&ANSIBuf>,
         width: usize,
     ) -> fmt::Result
     where
@@ -1204,7 +1204,7 @@ mod grid_not_spanned {
     fn print_indent<F, C>(f: &mut F, c: char, n: usize, color: Option<C>) -> fmt::Result
     where
         F: Write,
-        C: Color,
+        C: ANSIFmt,
     {
         if n == 0 {
             return Ok(());
@@ -1212,9 +1212,9 @@ mod grid_not_spanned {
 
         match color {
             Some(color) => {
-                color.fmt_prefix(f)?;
+                color.fmt_ansi_prefix(f)?;
                 repeat_char(f, c, n)?;
-                color.fmt_suffix(f)
+                color.fmt_ansi_suffix(f)
             }
             None => repeat_char(f, c, n),
         }
@@ -1223,7 +1223,7 @@ mod grid_not_spanned {
     fn print_indent2<F, C>(f: &mut F, c: &Colored<char, C>, n: usize) -> fmt::Result
     where
         F: Write,
-        C: Color,
+        C: ANSIFmt,
     {
         if n == 0 {
             return Ok(());
@@ -1231,9 +1231,9 @@ mod grid_not_spanned {
 
         match &c.color {
             Some(color) => {
-                color.fmt_prefix(f)?;
+                color.fmt_ansi_prefix(f)?;
                 repeat_char(f, c.data, n)?;
-                color.fmt_suffix(f)
+                color.fmt_ansi_suffix(f)
             }
             None => repeat_char(f, c.data, n),
         }
@@ -1241,12 +1241,12 @@ mod grid_not_spanned {
 
     /// Trims a string.
     fn string_trim(text: &str) -> Cow<'_, str> {
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         {
             ansi_str::AnsiStr::ansi_trim(text)
         }
 
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         {
             text.trim().into()
         }
@@ -1499,7 +1499,7 @@ mod grid_spanned {
         }
 
         if let Some(clr) = used_color {
-            clr.fmt_suffix(f)?;
+            clr.fmt_ansi_suffix(f)?;
         }
 
         Ok(())
@@ -1531,9 +1531,9 @@ mod grid_spanned {
 
         match color {
             Some(clr) => {
-                clr.fmt_prefix(f)?;
+                clr.fmt_ansi_prefix(f)?;
                 f.write_char(symbol)?;
-                clr.fmt_suffix(f)?;
+                clr.fmt_ansi_suffix(f)?;
             }
             None => f.write_char(symbol)?,
         }
@@ -1546,7 +1546,7 @@ mod grid_spanned {
         cfg: &'a SpannedConfig,
         pos: Position,
         shape: Shape,
-        used_color: &mut Option<&'a AnsiColor<'static>>,
+        used_color: &mut Option<&'a ANSIBuf>,
     ) -> fmt::Result
     where
         F: fmt::Write,
@@ -1573,10 +1573,10 @@ mod grid_spanned {
         Ok(())
     }
 
-    fn prepare_coloring<'a, 'b, F>(
+    fn prepare_coloring<'a, F>(
         f: &mut F,
-        clr: Option<&'a AnsiColor<'b>>,
-        used_color: &mut Option<&'a AnsiColor<'b>>,
+        clr: Option<&'a ANSIBuf>,
+        used_color: &mut Option<&'a ANSIBuf>,
     ) -> fmt::Result
     where
         F: Write,
@@ -1585,19 +1585,19 @@ mod grid_spanned {
             Some(clr) => match used_color.as_mut() {
                 Some(used_clr) => {
                     if **used_clr != *clr {
-                        used_clr.fmt_suffix(f)?;
-                        clr.fmt_prefix(f)?;
+                        used_clr.fmt_ansi_suffix(f)?;
+                        clr.fmt_ansi_prefix(f)?;
                         *used_clr = clr;
                     }
                 }
                 None => {
-                    clr.fmt_prefix(f)?;
+                    clr.fmt_ansi_prefix(f)?;
                     *used_color = Some(clr);
                 }
             },
             None => {
                 if let Some(clr) = used_color.take() {
-                    clr.fmt_suffix(f)?
+                    clr.fmt_ansi_suffix(f)?
                 }
             }
         }
@@ -1641,7 +1641,7 @@ mod grid_spanned {
         }
 
         if let Some(clr) = used_color.take() {
-            clr.fmt_suffix(f)?;
+            clr.fmt_ansi_suffix(f)?;
         }
 
         Ok(())
@@ -1653,7 +1653,7 @@ mod grid_spanned {
         pos: Position,
         width: usize,
         c: char,
-        used_color: &Option<&AnsiColor<'static>>,
+        used_color: &Option<&ANSIBuf>,
     ) -> fmt::Result
     where
         F: Write,
@@ -1667,16 +1667,16 @@ mod grid_spanned {
             match cfg.lookup_horizontal_color(pos, i, width) {
                 Some(color) => match used_color {
                     Some(clr) => {
-                        clr.fmt_suffix(f)?;
-                        color.fmt_prefix(f)?;
+                        clr.fmt_ansi_suffix(f)?;
+                        color.fmt_ansi_prefix(f)?;
                         f.write_char(c)?;
-                        color.fmt_suffix(f)?;
-                        clr.fmt_prefix(f)?;
+                        color.fmt_ansi_suffix(f)?;
+                        clr.fmt_ansi_prefix(f)?;
                     }
                     None => {
-                        color.fmt_prefix(f)?;
+                        color.fmt_ansi_prefix(f)?;
                         f.write_char(c)?;
-                        color.fmt_suffix(f)?;
+                        color.fmt_ansi_suffix(f)?;
                     }
                 },
                 _ => f.write_char(c)?,
@@ -1769,8 +1769,8 @@ mod grid_spanned {
     where
         F: Write,
         R: Records + PeekableRecords,
-        C: Color,
-        C1: Color,
+        C: ANSIFmt,
+        C1: ANSIFmt,
     {
         let line = records.get_line(pos, index);
         let (line, line_width) = if text_cfg.formatting.horizontal_trim {
@@ -1817,8 +1817,8 @@ mod grid_spanned {
     ) -> fmt::Result
     where
         F: Write,
-        C: Color,
-        C1: Color,
+        C: ANSIFmt,
+        C1: ANSIFmt,
     {
         print_indent(f, space.data, indent.left, space.color.as_ref())?;
         print_text(f, text.data, text.color)?;
@@ -1829,13 +1829,13 @@ mod grid_spanned {
     fn print_text<F, C>(f: &mut F, text: &str, clr: Option<C>) -> fmt::Result
     where
         F: Write,
-        C: Color,
+        C: ANSIFmt,
     {
         match clr {
             Some(color) => {
-                color.fmt_prefix(f)?;
+                color.fmt_ansi_prefix(f)?;
                 f.write_str(text)?;
-                color.fmt_suffix(f)
+                color.fmt_ansi_suffix(f)
             }
             None => f.write_str(text),
         }
@@ -1987,7 +1987,7 @@ mod grid_spanned {
         f: &mut F,
         indent: Indent,
         offset: Offset,
-        color: Option<&AnsiColor<'_>>,
+        color: Option<&ANSIBuf>,
         line: usize,
         height: usize,
     ) -> fmt::Result
@@ -2026,7 +2026,7 @@ mod grid_spanned {
         f: &mut F,
         indent: &Indent,
         offset: &Offset,
-        color: Option<&AnsiColor<'_>>,
+        color: Option<&ANSIBuf>,
         width: usize,
     ) -> fmt::Result
     where
@@ -2069,7 +2069,7 @@ mod grid_spanned {
     fn print_indent<F, C>(f: &mut F, c: char, n: usize, color: Option<C>) -> fmt::Result
     where
         F: Write,
-        C: Color,
+        C: ANSIFmt,
     {
         if n == 0 {
             return Ok(());
@@ -2077,9 +2077,9 @@ mod grid_spanned {
 
         match color {
             Some(color) => {
-                color.fmt_prefix(f)?;
+                color.fmt_ansi_prefix(f)?;
                 repeat_char(f, c, n)?;
-                color.fmt_suffix(f)
+                color.fmt_ansi_suffix(f)
             }
             None => repeat_char(f, c, n),
         }
@@ -2155,12 +2155,12 @@ mod grid_spanned {
 
     /// Trims a string.
     fn string_trim(text: &str) -> Cow<'_, str> {
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         {
             ansi_str::AnsiStr::ansi_trim(text)
         }
 
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         {
             text.trim().into()
         }
diff --git a/papergrid/src/lib.rs b/papergrid/src/lib.rs
index 8da4f14b..26fbfa14 100644
--- a/papergrid/src/lib.rs
+++ b/papergrid/src/lib.rs
@@ -78,7 +78,7 @@
 //! );
 //! ```
 
-pub mod color;
+pub mod ansi;
 pub mod colors;
 pub mod config;
 pub mod dimension;
diff --git a/papergrid/src/util/string.rs b/papergrid/src/util/string.rs
index 0017e6a9..7e7f4a88 100644
--- a/papergrid/src/util/string.rs
+++ b/papergrid/src/util/string.rs
@@ -7,7 +7,7 @@
 /// Returns string width and count lines of a string. It's a combination of [`string_width_multiline`] and [`count_lines`].
 #[cfg(feature = "std")]
 pub fn string_dimension(text: &str) -> (usize, usize) {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         let (lines, acc, max) = text.chars().fold((1, 0, 0), |(lines, acc, max), c| {
             if c == '\n' {
@@ -21,7 +21,7 @@ pub fn string_dimension(text: &str) -> (usize, usize) {
         (lines, acc.max(max))
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         get_lines(text)
             .map(|line| string_width(&line))
@@ -31,12 +31,12 @@ pub fn string_dimension(text: &str) -> (usize, usize) {
 
 /// Returns a string width.
 pub fn string_width(text: &str) -> usize {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         unicode_width::UnicodeWidthStr::width(text)
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         // we need to strip ansi because of terminal links
         // and they're can't be stripped by ansi_str.
@@ -51,7 +51,7 @@ pub fn string_width(text: &str) -> usize {
 
 /// Returns a max string width of a line.
 pub fn string_width_multiline(text: &str) -> usize {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         text.lines()
             .map(unicode_width::UnicodeWidthStr::width)
@@ -59,7 +59,7 @@ pub fn string_width_multiline(text: &str) -> usize {
             .unwrap_or(0)
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         text.lines().map(string_width).max().unwrap_or(0)
     }
@@ -82,7 +82,7 @@ pub fn count_tabs(s: &str) -> usize {
 /// Splits the string by lines.
 #[cfg(feature = "std")]
 pub fn get_lines(text: &str) -> Lines<'_> {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         // we call `split()` but not `lines()` in order to match colored implementation
         // specifically how we treat a trailing '\n' character.
@@ -91,7 +91,7 @@ pub fn get_lines(text: &str) -> Lines<'_> {
         }
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         Lines {
             inner: ansi_str::AnsiStr::ansi_split(text, "\n"),
@@ -105,9 +105,9 @@ pub fn get_lines(text: &str) -> Lines<'_> {
 #[allow(missing_debug_implementations)]
 #[cfg(feature = "std")]
 pub struct Lines<'a> {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     inner: std::str::Split<'a, char>,
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     inner: ansi_str::AnsiSplit<'a>,
 }
 #[cfg(feature = "std")]
@@ -115,12 +115,12 @@ impl<'a> Iterator for Lines<'a> {
     type Item = std::borrow::Cow<'a, str>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         {
             self.inner.next().map(std::borrow::Cow::Borrowed)
         }
 
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         {
             self.inner.next()
         }
@@ -186,7 +186,7 @@ mod tests {
         assert_eq!(string_width_multiline("Go 👍\nC 😎"), 5);
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn colored_string_width_test() {
         use owo_colors::OwoColorize;
@@ -208,7 +208,7 @@ mod tests {
         assert_eq!(count_lines("now is the time for all good men\n"), 2);
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn string_width_multinline_for_link() {
         assert_eq!(
@@ -219,7 +219,7 @@ mod tests {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn string_width_for_link() {
         assert_eq!(
@@ -234,11 +234,11 @@ mod tests {
         assert_eq!(
             string_dimension("\u{1b}[37mnow is the time for all good men\n\u{1b}[0m"),
             {
-                #[cfg(feature = "color")]
+                #[cfg(feature = "ansi")]
                 {
                     (2, 32)
                 }
-                #[cfg(not(feature = "color"))]
+                #[cfg(not(feature = "ansi"))]
                 {
                     (2, 36)
                 }
diff --git a/ron_to_table/Cargo.toml b/ron_to_table/Cargo.toml
index 30c156ff..13b3d2f0 100644
--- a/ron_to_table/Cargo.toml
+++ b/ron_to_table/Cargo.toml
@@ -13,11 +13,13 @@ description = "A library for pretty print RON as a table"
 license = "MIT"
 
 [features]
-color = ["tabled/color"]
+ansi = ["tabled/ansi"]
+derive = ["tabled/derive"]
+macros = ["tabled/macros"]
 
 [dependencies]
 ron = "0.8"
 tabled = { path = "../tabled", features = ["std"], default-features = false }
 
 [dev-dependencies]
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
diff --git a/ron_to_table/src/table.rs b/ron_to_table/src/table.rs
index 7e1a688c..983f15ca 100644
--- a/ron_to_table/src/table.rs
+++ b/ron_to_table/src/table.rs
@@ -70,7 +70,7 @@ impl RonTable {
     /// Apply settings to the table.
     pub fn with<O>(&mut self, option: O) -> &mut Self
     where
-        O: TableOption<EmptyRecords, CompleteDimension<'static>, CompactMultilineConfig>,
+        O: TableOption<EmptyRecords, CompactMultilineConfig, CompleteDimension<'static>>,
     {
         let mut records = EmptyRecords::default();
         let mut dims = CompleteDimension::default();
diff --git a/static_table/Cargo.toml b/static_table/Cargo.toml
index 4330dbd9..8aa049a6 100644
--- a/static_table/Cargo.toml
+++ b/static_table/Cargo.toml
@@ -15,7 +15,9 @@ license = "MIT"
 proc-macro = true
 
 [features]
-color = ["tabled/color"]
+ansi = ["tabled/ansi"]
+derive = ["tabled/derive"]
+macros = ["tabled/macros"]
 
 [dependencies]
 tabled = { path = "../tabled", features = ["std"], default-features = false }
@@ -25,4 +27,4 @@ proc-macro2 = "1"
 proc-macro-error = "1.0"
 
 [dev-dependencies]
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
diff --git a/table_to_html/Cargo.toml b/table_to_html/Cargo.toml
index f34df267..138eca26 100644
--- a/table_to_html/Cargo.toml
+++ b/table_to_html/Cargo.toml
@@ -11,9 +11,14 @@ keywords = ["table", "print", "pretty-table", "format", "html"]
 categories = ["text-processing", "visualization"]
 license = "MIT"
 
+[features]
+ansi = ["tabled/ansi"]
+derive = ["tabled/derive"]
+macros = ["tabled/macros"]
+
 [dependencies]
 tabled = { path = "../tabled", features = ["std"], default-features = false }
 
 [dev-dependencies]
 tabled = { path = "../tabled", features = ["std", "derive"], default-features = false }
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
diff --git a/tabled/Cargo.toml b/tabled/Cargo.toml
index 7fcd84cf..3882c7ef 100644
--- a/tabled/Cargo.toml
+++ b/tabled/Cargo.toml
@@ -19,7 +19,7 @@ maintenance = { status = "actively-developed" }
 
 [[example]]
 name = "color"
-required-features = ["color", "derive"]
+required-features = ["ansi", "derive"]
 
 [[example]]
 name = "colored_borders"
@@ -28,7 +28,7 @@ required-features = ["derive"]
 [[example]]
 name = "colored_padding"
 path = "examples/colored_padding.rs"
-required-features = ["color", "derive"]
+required-features = ["ansi", "derive"]
 
 [[example]]
 name = "disable"
@@ -147,7 +147,7 @@ required-features = ["derive"]
 [[example]]
 name = "hyperlink"
 path = "examples/hyperlink.rs"
-required-features = ["derive", "color"]
+required-features = ["derive", "ansi"]
 
 [[example]]
 name = "highlight"
@@ -293,7 +293,7 @@ required-features = ["derive", "std"]
 default = ["derive", "macros"]
 std = ["papergrid/std"]
 derive = ["tabled_derive", "std"]
-color = ["papergrid/color", "ansi-str", "ansitok", "std"]
+ansi = ["papergrid/ansi", "ansi-str", "ansitok", "std"]
 macros = ["std"]
 
 [dependencies]
@@ -305,7 +305,7 @@ unicode-width = "0.1"
 
 [dev-dependencies]
 owo-colors = "3.5"
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
 
 # To run it locally (probably need to `add #![feature(doc_cfg)]` to the crate attributes to enable.
 #
diff --git a/tabled/benches/functions/Cargo.toml b/tabled/benches/functions/Cargo.toml
index 006da7cb..ab5de84e 100644
--- a/tabled/benches/functions/Cargo.toml
+++ b/tabled/benches/functions/Cargo.toml
@@ -10,8 +10,8 @@ edition = "2021"
 [dependencies]
 
 [dev-dependencies]
-tabled = { path = "../../..", features = ["color"] }
-tabled_master = { version = "0.10.0", features = ["color"], package = "tabled"}
+tabled = { path = "../../..", features = ["ansi"] }
+tabled_master = { version = "0.10.0", features = ["ansi"], package = "tabled"}
 
 owo-colors = "3.5.0"
 criterion = { version = "0.4.0", features = ["html_reports"] }
diff --git a/tabled/benches/lib_comp/crates/tabled_color/Cargo.toml b/tabled/benches/lib_comp/crates/tabled_color/Cargo.toml
index 2e96d640..8788577a 100644
--- a/tabled/benches/lib_comp/crates/tabled_color/Cargo.toml
+++ b/tabled/benches/lib_comp/crates/tabled_color/Cargo.toml
@@ -6,4 +6,4 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-tabled = { version = "0.10.0", default-features = false, features = ["color"] }
+tabled = { version = "0.10.0", default-features = false, features = ["ansi"] }
diff --git a/tabled/benches/lib_comp/crates/tabled_color_current/Cargo.toml b/tabled/benches/lib_comp/crates/tabled_color_current/Cargo.toml
index d1274651..35d9d17a 100644
--- a/tabled/benches/lib_comp/crates/tabled_color_current/Cargo.toml
+++ b/tabled/benches/lib_comp/crates/tabled_color_current/Cargo.toml
@@ -6,4 +6,4 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-tabled = { path = "../../../..", default-features = false, features = ["color"] }
+tabled = { path = "../../../..", default-features = false, features = ["ansi"] }
diff --git a/tabled/examples/show/Cargo.toml b/tabled/examples/show/Cargo.toml
index f6841dc7..09df83cd 100644
--- a/tabled/examples/show/Cargo.toml
+++ b/tabled/examples/show/Cargo.toml
@@ -8,6 +8,6 @@ edition = "2021"
 [workspace]
 
 [dependencies]
-tabled = { path = "../..", features = ["color", "derive"] }
+tabled = { path = "../..", features = ["ansi", "derive"] }
 crossterm = "0.25.0"
 clap = { version = "4.1.6", features = ["cargo", "derive"] }
diff --git a/tabled/src/grid/colored_config.rs b/tabled/src/grid/colored_config.rs
index fafd428d..09640c74 100644
--- a/tabled/src/grid/colored_config.rs
+++ b/tabled/src/grid/colored_config.rs
@@ -1,7 +1,7 @@
 use std::ops::{Deref, DerefMut};
 
 use crate::grid::{
-    color::AnsiColor,
+    ansi::ANSIBuf,
     config::{Entity, EntityMap, SpannedConfig},
 };
 
@@ -27,7 +27,7 @@ impl ColoredConfig {
     /// While this method works in all contexts.
     ///
     /// [`Format`]: crate::settings::Format
-    pub fn set_color(&mut self, pos: Entity, color: AnsiColor<'static>) -> &mut Self {
+    pub fn set_color(&mut self, pos: Entity, color: ANSIBuf) -> &mut Self {
         match self.colors.0.as_mut() {
             Some(map) => map.insert(pos, color),
             None => {
@@ -41,7 +41,7 @@ impl ColoredConfig {
     }
 
     /// Set a list of colors.
-    pub fn set_colors(&mut self, colors: EntityMap<AnsiColor<'static>>) -> &mut Self {
+    pub fn set_colors(&mut self, colors: EntityMap<ANSIBuf>) -> &mut Self {
         self.colors = ColorMap(Some(colors));
         self
     }
@@ -94,7 +94,7 @@ impl AsRef<SpannedConfig> for ColoredConfig {
 
 /// A colors structure for [`ColoredConfig`].
 #[derive(Debug, Default, PartialEq, Eq, Clone)]
-pub struct ColorMap(Option<EntityMap<AnsiColor<'static>>>);
+pub struct ColorMap(Option<EntityMap<ANSIBuf>>);
 
 impl ColorMap {
     /// Checks if any colors is set on.
@@ -104,7 +104,7 @@ impl ColorMap {
 }
 
 impl crate::grid::colors::Colors for ColorMap {
-    type Color = AnsiColor<'static>;
+    type Color = ANSIBuf;
 
     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 1c069b62..623a50a1 100644
--- a/tabled/src/grid/compact_multiline_config.rs
+++ b/tabled/src/grid/compact_multiline_config.rs
@@ -1,5 +1,5 @@
 use crate::grid::{
-    color::StaticColor,
+    ansi::ANSIStr,
     config::{
         AlignmentHorizontal, AlignmentVertical, Borders, CompactConfig, Formatting, Indent, Sides,
     },
@@ -63,7 +63,7 @@ impl CompactMultilineConfig {
     }
 
     /// Returns a current [`Borders`] structure.
-    pub const fn get_borders_color(&self) -> &Borders<StaticColor> {
+    pub const fn get_borders_color(&self) -> &Borders<ANSIStr<'static>> {
         self.config.get_borders_color()
     }
 
@@ -88,27 +88,27 @@ impl CompactMultilineConfig {
     }
 
     /// Sets colors of border carcass on the grid.
-    pub fn set_borders_color(&mut self, borders: Borders<StaticColor>) {
+    pub fn set_borders_color(&mut self, borders: Borders<ANSIStr<'static>>) {
         self.config = self.config.set_borders_color(borders)
     }
 
     /// Set colors for a margin.
-    pub fn set_margin_color(&mut self, color: Sides<StaticColor>) {
+    pub fn set_margin_color(&mut self, color: Sides<ANSIStr<'static>>) {
         self.config = self.config.set_margin_color(color)
     }
 
     /// Returns a margin color.
-    pub const fn get_margin_color(&self) -> &Sides<StaticColor> {
+    pub const fn get_margin_color(&self) -> &Sides<ANSIStr<'static>> {
         self.config.get_margin_color()
     }
 
     /// Set a padding color to all cells.
-    pub fn set_padding_color(&mut self, color: Sides<StaticColor>) {
+    pub fn set_padding_color(&mut self, color: Sides<ANSIStr<'static>>) {
         self.config = self.config.set_padding_color(color)
     }
 
     /// get a padding color.
-    pub const fn get_padding_color(&self) -> &Sides<StaticColor> {
+    pub const fn get_padding_color(&self) -> &Sides<ANSIStr<'static>> {
         self.config.get_padding_color()
     }
 
diff --git a/tabled/src/grid/mod.rs b/tabled/src/grid/mod.rs
index db030133..7ea92d23 100644
--- a/tabled/src/grid/mod.rs
+++ b/tabled/src/grid/mod.rs
@@ -12,7 +12,7 @@ mod compact_multiline_config;
 pub mod dimension;
 pub mod records;
 
-pub use papergrid::color;
+pub use papergrid::ansi;
 pub use papergrid::colors;
 pub use papergrid::util;
 
diff --git a/tabled/src/settings/alignment/mod.rs b/tabled/src/settings/alignment/mod.rs
index f864ef40..e254571c 100644
--- a/tabled/src/settings/alignment/mod.rs
+++ b/tabled/src/settings/alignment/mod.rs
@@ -163,7 +163,7 @@ impl<R> crate::settings::CellOption<R, ColoredConfig> for Alignment {
 }
 
 #[cfg(feature = "std")]
-impl<R, D> TableOption<R, D, ColoredConfig> for Alignment {
+impl<R, D> TableOption<R, ColoredConfig, D> for Alignment {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         match self.inner {
             Horizontal(a) => cfg.set_alignment_horizontal(Entity::Global, a),
@@ -176,7 +176,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for Alignment {
     }
 }
 
-impl<R, D> TableOption<R, D, CompactConfig> for Alignment {
+impl<R, D> TableOption<R, CompactConfig, D> for Alignment {
     fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         if let Horizontal(a) = self.inner {
             *cfg = cfg.set_alignment_horizontal(a)
@@ -188,7 +188,7 @@ impl<R, D> TableOption<R, D, CompactConfig> for Alignment {
     }
 }
 
-impl<R, D> TableOption<R, D, CompactMultilineConfig> for Alignment {
+impl<R, D> TableOption<R, CompactMultilineConfig, D> for Alignment {
     fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
         match self.inner {
             Horizontal(a) => cfg.set_alignment_horizontal(a),
diff --git a/tabled/src/settings/color/mod.rs b/tabled/src/settings/color/mod.rs
index 9851396e..c793b31d 100644
--- a/tabled/src/settings/color/mod.rs
+++ b/tabled/src/settings/color/mod.rs
@@ -3,11 +3,11 @@
 //! [`Border`]: crate::settings::Border
 //! [`Table`]: crate::Table
 
-use std::{borrow::Cow, ops::BitOr};
+use std::{fmt, ops::BitOr};
 
 use crate::{
     grid::{
-        color::{AnsiColor, StaticColor},
+        ansi::{ANSIBuf, ANSIFmt, ANSIStr as StaticColor},
         config::{ColoredConfig, Entity},
     },
     settings::{CellOption, TableOption},
@@ -35,172 +35,214 @@ use crate::{
 /// [`Padding`]: crate::settings::Padding
 /// [`Margin`]: crate::settings::Margin
 /// [`Border`]: crate::settings::Border
-#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct Color(AnsiColor<'static>);
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Color {
+    inner: ColorInner,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+enum ColorInner {
+    Static(StaticColor<'static>),
+    Allocated(ANSIBuf),
+}
 
 #[rustfmt::skip]
 impl Color {
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BLACK:          Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[30m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BLACK:          Self = Self::new_static("\u{1b}[30m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BLUE:           Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[34m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BLUE:           Self = Self::new_static("\u{1b}[34m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_BLACK:   Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[90m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_BLACK:   Self = Self::new_static("\u{1b}[90m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_BLUE:    Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[94m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_BLUE:    Self = Self::new_static("\u{1b}[94m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_CYAN:    Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[96m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_CYAN:    Self = Self::new_static("\u{1b}[96m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_GREEN:   Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[92m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_GREEN:   Self = Self::new_static("\u{1b}[92m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_MAGENTA: Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[95m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_MAGENTA: Self = Self::new_static("\u{1b}[95m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_RED:     Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[91m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_RED:     Self = Self::new_static("\u{1b}[91m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_WHITE:   Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[97m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_WHITE:   Self = Self::new_static("\u{1b}[97m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_BRIGHT_YELLOW:  Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[93m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_BRIGHT_YELLOW:  Self = Self::new_static("\u{1b}[93m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_CYAN:           Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[36m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_CYAN:           Self = Self::new_static("\u{1b}[36m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_GREEN:          Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[32m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_GREEN:          Self = Self::new_static("\u{1b}[32m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_MAGENTA:        Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[35m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_MAGENTA:        Self = Self::new_static("\u{1b}[35m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_RED:            Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[31m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_RED:            Self = Self::new_static("\u{1b}[31m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_WHITE:          Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[37m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_WHITE:          Self = Self::new_static("\u{1b}[37m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const FG_YELLOW:         Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[33m"), Cow::Borrowed("\u{1b}[39m")));
+    pub const FG_YELLOW:         Self = Self::new_static("\u{1b}[33m", "\u{1b}[39m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
 
-    pub const BG_BLACK:          Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[40m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BLACK:          Self = Self::new_static("\u{1b}[40m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BLUE:           Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[44m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BLUE:           Self = Self::new_static("\u{1b}[44m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_BLACK:   Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[100m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_BLACK:   Self = Self::new_static("\u{1b}[100m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_BLUE:    Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[104m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_BLUE:    Self = Self::new_static("\u{1b}[104m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_CYAN:    Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[106m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_CYAN:    Self = Self::new_static("\u{1b}[106m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_GREEN:   Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[102m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_GREEN:   Self = Self::new_static("\u{1b}[102m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_MAGENTA: Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[105m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_MAGENTA: Self = Self::new_static("\u{1b}[105m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_RED:     Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[101m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_RED:     Self = Self::new_static("\u{1b}[101m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_WHITE:   Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[107m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_WHITE:   Self = Self::new_static("\u{1b}[107m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_BRIGHT_YELLOW:  Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[103m"), Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_BRIGHT_YELLOW:  Self = Self::new_static("\u{1b}[103m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_CYAN:           Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[46m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_CYAN:           Self = Self::new_static("\u{1b}[46m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_GREEN:          Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[42m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_GREEN:          Self = Self::new_static("\u{1b}[42m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_MAGENTA:        Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[45m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_MAGENTA:        Self = Self::new_static("\u{1b}[45m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_RED:            Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[41m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_RED:            Self = Self::new_static("\u{1b}[41m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_WHITE:          Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[47m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_WHITE:          Self = Self::new_static("\u{1b}[47m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BG_YELLOW:         Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[43m"),  Cow::Borrowed("\u{1b}[49m")));
+    pub const BG_YELLOW:         Self = Self::new_static("\u{1b}[43m", "\u{1b}[49m");
     /// A color representation.
     /// 
     /// Notice that the colors are constants so you can't combine them.
-    pub const BOLD:              Self = Self(AnsiColor::new(Cow::Borrowed("\u{1b}[1m"),  Cow::Borrowed("\u{1b}[22m")));
+    pub const BOLD:              Self = Self::new_static("\u{1b}[1m", "\u{1b}[22m");
 }
 
 impl Color {
     /// Creates a new [`Color`]` instance, with ANSI prefix and ANSI suffix.
     /// You can use [`TryFrom`] to construct it from [`String`].
-    pub fn new(prefix: String, suffix: String) -> Self {
-        Self(AnsiColor::new(prefix.into(), suffix.into()))
+    pub fn new<P, S>(prefix: P, suffix: S) -> Self
+    where
+        P: Into<String>,
+        S: Into<String>,
+    {
+        let color = ANSIBuf::new(prefix, suffix);
+        let inner = ColorInner::Allocated(color);
+
+        Self { inner }
+    }
+
+    const fn new_static(prefix: &'static str, suffix: &'static str) -> Self {
+        let color = StaticColor::new(prefix, suffix);
+        let inner = ColorInner::Static(color);
+
+        Self { inner }
+    }
+
+    /// Return a prefix.
+    pub fn get_prefix(&self) -> &str {
+        match &self.inner {
+            ColorInner::Static(color) => color.get_prefix(),
+            ColorInner::Allocated(color) => color.get_prefix(),
+        }
+    }
+
+    /// Return a suffix.
+    pub fn get_suffix(&self) -> &str {
+        match &self.inner {
+            ColorInner::Static(color) => color.get_suffix(),
+            ColorInner::Allocated(color) => color.get_suffix(),
+        }
     }
 }
 
-impl From<Color> for AnsiColor<'static> {
-    fn from(c: Color) -> Self {
-        c.0
+impl Default for Color {
+    fn default() -> Self {
+        Self {
+            inner: ColorInner::Static(StaticColor::default()),
+        }
     }
 }
 
-impl From<AnsiColor<'static>> for Color {
-    fn from(c: AnsiColor<'static>) -> Self {
-        Self(c)
+impl From<Color> for ANSIBuf {
+    fn from(color: Color) -> Self {
+        match color.inner {
+            ColorInner::Static(color) => ANSIBuf::from(color),
+            ColorInner::Allocated(color) => color,
+        }
     }
 }
 
-impl From<StaticColor> for Color {
-    fn from(c: StaticColor) -> Self {
-        Self(AnsiColor::new(
-            Cow::Borrowed(c.get_prefix()),
-            Cow::Borrowed(c.get_suffix()),
-        ))
+impl From<ANSIBuf> for Color {
+    fn from(color: ANSIBuf) -> Self {
+        Self {
+            inner: ColorInner::Allocated(color),
+        }
     }
 }
 
@@ -208,10 +250,10 @@ impl BitOr for Color {
     type Output = Color;
 
     fn bitor(self, rhs: Self) -> Self::Output {
-        let l_prefix = self.0.get_prefix();
-        let l_suffix = self.0.get_suffix();
-        let r_prefix = rhs.0.get_prefix();
-        let r_suffix = rhs.0.get_suffix();
+        let l_prefix = self.get_prefix();
+        let l_suffix = self.get_suffix();
+        let r_prefix = rhs.get_prefix();
+        let r_suffix = rhs.get_suffix();
 
         let mut prefix = l_prefix.to_string();
         if l_prefix != r_prefix {
@@ -227,27 +269,36 @@ impl BitOr for Color {
     }
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 impl std::convert::TryFrom<&str> for Color {
     type Error = ();
 
     fn try_from(value: &str) -> Result<Self, Self::Error> {
-        AnsiColor::try_from(value).map(Color)
+        let buf = ANSIBuf::try_from(value)?;
+
+        Ok(Color {
+            inner: ColorInner::Allocated(buf),
+        })
     }
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 impl std::convert::TryFrom<String> for Color {
     type Error = ();
 
     fn try_from(value: String) -> Result<Self, Self::Error> {
-        AnsiColor::try_from(value).map(Color)
+        let buf = ANSIBuf::try_from(value)?;
+
+        Ok(Color {
+            inner: ColorInner::Allocated(buf),
+        })
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for Color {
+impl<R, D> TableOption<R, ColoredConfig, D> for Color {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-        let _ = cfg.set_color(Entity::Global, self.0.clone());
+        let color = self.into();
+        let _ = cfg.set_color(Entity::Global, color);
     }
 
     fn hint_change(&self) -> Option<Entity> {
@@ -257,7 +308,8 @@ impl<R, D> TableOption<R, D, ColoredConfig> for Color {
 
 impl<R> CellOption<R, ColoredConfig> for Color {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
-        let _ = cfg.set_color(entity, self.0.clone());
+        let color = self.into();
+        let _ = cfg.set_color(entity, color);
     }
 
     fn hint_change(&self) -> Option<Entity> {
@@ -267,7 +319,8 @@ impl<R> CellOption<R, ColoredConfig> for Color {
 
 impl<R> CellOption<R, ColoredConfig> for &Color {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
-        let _ = cfg.set_color(entity, self.0.clone());
+        let color = self.clone().into();
+        let _ = cfg.set_color(entity, color);
     }
 
     fn hint_change(&self) -> Option<Entity> {
@@ -275,17 +328,19 @@ impl<R> CellOption<R, ColoredConfig> 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)
-    }
-
-    fn fmt_suffix<W: std::fmt::Write>(&self, f: &mut W) -> std::fmt::Result {
-        self.0.fmt_suffix(f)
+impl ANSIFmt for Color {
+    fn fmt_ansi_prefix<W: fmt::Write>(&self, f: &mut W) -> fmt::Result {
+        match &self.inner {
+            ColorInner::Static(color) => color.fmt_ansi_prefix(f),
+            ColorInner::Allocated(color) => color.fmt_ansi_prefix(f),
+        }
     }
 
-    fn colorize<W: std::fmt::Write>(&self, f: &mut W, text: &str) -> std::fmt::Result {
-        self.0.colorize(f, text)
+    fn fmt_ansi_suffix<W: fmt::Write>(&self, f: &mut W) -> fmt::Result {
+        match &self.inner {
+            ColorInner::Static(color) => color.fmt_ansi_suffix(f),
+            ColorInner::Allocated(color) => color.fmt_ansi_suffix(f),
+        }
     }
 }
 
@@ -293,64 +348,43 @@ impl crate::grid::color::Color for Color {
 mod tests {
     use super::*;
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     use ::{owo_colors::OwoColorize, std::convert::TryFrom};
 
     #[test]
     fn test_xor_operation() {
         assert_eq!(
             Color::FG_BLACK | Color::FG_BLUE,
-            Color::new(
-                String::from("\u{1b}[30m\u{1b}[34m"),
-                String::from("\u{1b}[39m")
-            )
+            Color::new("\u{1b}[30m\u{1b}[34m", "\u{1b}[39m")
         );
         assert_eq!(
             Color::FG_BRIGHT_GREEN | Color::BG_BLUE,
-            Color::new(
-                String::from("\u{1b}[92m\u{1b}[44m"),
-                String::from("\u{1b}[39m\u{1b}[49m")
-            )
+            Color::new("\u{1b}[92m\u{1b}[44m", "\u{1b}[39m\u{1b}[49m")
         );
         assert_eq!(
-            Color::new(String::from("..."), String::from("!!!"))
-                | Color::new(String::from("@@@"), String::from("###")),
-            Color::new(String::from("...@@@"), String::from("!!!###"))
+            Color::new("...", "!!!") | Color::new("@@@", "###"),
+            Color::new("...@@@", "!!!###")
         );
         assert_eq!(
-            Color::new(String::from("..."), String::from("!!!"))
-                | Color::new(String::from("@@@"), String::from("###"))
-                | Color::new(String::from("$$$"), String::from("%%%")),
-            Color::new(String::from("...@@@$$$"), String::from("!!!###%%%"))
+            Color::new("...", "!!!") | Color::new("@@@", "###") | Color::new("$$$", "%%%"),
+            Color::new("...@@@$$$", "!!!###%%%")
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn test_try_from() {
         assert_eq!(Color::try_from(""), Err(()));
         assert_eq!(Color::try_from("".red().on_green().to_string()), Err(()));
-        assert_eq!(
-            Color::try_from("."),
-            Ok(Color::new(String::new(), String::new()))
-        );
-        assert_eq!(
-            Color::try_from("...."),
-            Ok(Color::new(String::new(), String::new()))
-        );
+        assert_eq!(Color::try_from("."), Ok(Color::new("", "")));
+        assert_eq!(Color::try_from("...."), Ok(Color::new("", "")));
         assert_eq!(
             Color::try_from(".".red().on_green().to_string()),
-            Ok(Color::new(
-                String::from("\u{1b}[31m\u{1b}[42m"),
-                String::from("\u{1b}[39m\u{1b}[49m")
-            ))
+            Ok(Color::new("\u{1b}[31m\u{1b}[42m", "\u{1b}[39m\u{1b}[49m"))
         );
         assert_eq!(
             Color::try_from("....".red().on_green().to_string()),
-            Ok(Color::new(
-                String::from("\u{1b}[31m\u{1b}[42m"),
-                String::from("\u{1b}[39m\u{1b}[49m")
-            ))
+            Ok(Color::new("\u{1b}[31m\u{1b}[42m", "\u{1b}[39m\u{1b}[49m"))
         );
     }
 }
diff --git a/tabled/src/settings/concat/mod.rs b/tabled/src/settings/concat/mod.rs
index 23b0dcda..9f6fe1e4 100644
--- a/tabled/src/settings/concat/mod.rs
+++ b/tabled/src/settings/concat/mod.rs
@@ -114,7 +114,7 @@ impl Concat {
     }
 }
 
-impl<R, D, C> TableOption<R, D, C> for Concat
+impl<R, D, C> TableOption<R, C, D> for Concat
 where
     R: Records + ExactRecords + Resizable + PeekableRecords + RecordsMut<String>,
 {
diff --git a/tabled/src/settings/disable/mod.rs b/tabled/src/settings/disable/mod.rs
index 28346181..bd927dca 100644
--- a/tabled/src/settings/disable/mod.rs
+++ b/tabled/src/settings/disable/mod.rs
@@ -148,7 +148,7 @@ pub struct TargetRow;
 #[derive(Debug)]
 pub struct TargetColumn;
 
-impl<L, R, D, C> TableOption<R, D, C> for Disable<L, TargetColumn>
+impl<L, R, D, C> TableOption<R, C, D> for Disable<L, TargetColumn>
 where
     L: Location<R, Coordinate = usize>,
     R: Records + Resizable,
@@ -171,7 +171,7 @@ where
     }
 }
 
-impl<L, R, D, C> TableOption<R, D, C> for Disable<L, TargetRow>
+impl<L, R, D, C> TableOption<R, C, D> for Disable<L, TargetRow>
 where
     L: Location<R, Coordinate = usize>,
     R: ExactRecords + Resizable,
diff --git a/tabled/src/settings/duplicate/mod.rs b/tabled/src/settings/duplicate/mod.rs
index 3d56d8b4..07012814 100644
--- a/tabled/src/settings/duplicate/mod.rs
+++ b/tabled/src/settings/duplicate/mod.rs
@@ -76,7 +76,7 @@ impl<Dst, Src> Dup<Dst, Src> {
     }
 }
 
-impl<Dst, Src, R, D, C> TableOption<R, D, C> for Dup<Dst, Src>
+impl<Dst, Src, R, D, C> TableOption<R, C, D> for Dup<Dst, Src>
 where
     Dst: Object<R>,
     Src: Object<R>,
diff --git a/tabled/src/settings/extract/mod.rs b/tabled/src/settings/extract/mod.rs
index bba90a0d..6d984e1a 100644
--- a/tabled/src/settings/extract/mod.rs
+++ b/tabled/src/settings/extract/mod.rs
@@ -149,7 +149,7 @@ where
     }
 }
 
-impl<R, C, RR, D, Cfg> TableOption<RR, D, Cfg> for Extract<R, C>
+impl<R, C, RR, D, Cfg> TableOption<RR, Cfg, D> for Extract<R, C>
 where
     R: RangeBounds<usize> + Clone,
     C: RangeBounds<usize> + Clone,
diff --git a/tabled/src/settings/format/format_config.rs b/tabled/src/settings/format/format_config.rs
index 247ead34..0aea30e8 100644
--- a/tabled/src/settings/format/format_config.rs
+++ b/tabled/src/settings/format/format_config.rs
@@ -4,7 +4,7 @@ use crate::settings::TableOption;
 #[derive(Debug)]
 pub struct FormatConfig<F>(pub(crate) F);
 
-impl<F, R, D, C> TableOption<R, D, C> for FormatConfig<F>
+impl<F, R, D, C> TableOption<R, C, D> for FormatConfig<F>
 where
     F: FnMut(&mut C),
 {
diff --git a/tabled/src/settings/format/format_content.rs b/tabled/src/settings/format/format_content.rs
index c14eee64..b6263b50 100644
--- a/tabled/src/settings/format/format_content.rs
+++ b/tabled/src/settings/format/format_content.rs
@@ -38,7 +38,7 @@ impl<F> FormatContent<F> {
     }
 }
 
-impl<F, R, D, C> TableOption<R, D, C> for FormatContent<F>
+impl<F, R, D, C> TableOption<R, C, D> for FormatContent<F>
 where
     F: FnMut(&str) -> String + Clone,
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
diff --git a/tabled/src/settings/format/format_positioned.rs b/tabled/src/settings/format/format_positioned.rs
index e121f007..c2936dbc 100644
--- a/tabled/src/settings/format/format_positioned.rs
+++ b/tabled/src/settings/format/format_positioned.rs
@@ -18,7 +18,7 @@ impl<F> FormatContentPositioned<F> {
     }
 }
 
-impl<F, R, D, C> TableOption<R, D, C> for FormatContentPositioned<F>
+impl<F, R, D, C> TableOption<R, C, D> for FormatContentPositioned<F>
 where
     F: FnMut(&str, (usize, usize)) -> String,
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
diff --git a/tabled/src/settings/formatting/alignment_strategy.rs b/tabled/src/settings/formatting/alignment_strategy.rs
index 547ebec6..32b23d20 100644
--- a/tabled/src/settings/formatting/alignment_strategy.rs
+++ b/tabled/src/settings/formatting/alignment_strategy.rs
@@ -153,7 +153,7 @@ impl<R> CellOption<R, ColoredConfig> for AlignmentStrategy {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for AlignmentStrategy {
+impl<R, D> TableOption<R, ColoredConfig, D> for AlignmentStrategy {
     fn change(self, records: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         <Self as CellOption<R, ColoredConfig>>::change(self, records, cfg, Entity::Global)
     }
@@ -163,7 +163,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for AlignmentStrategy {
     }
 }
 
-impl<R, D> TableOption<R, D, CompactMultilineConfig> for AlignmentStrategy {
+impl<R, D> TableOption<R, CompactMultilineConfig, D> for AlignmentStrategy {
     fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
         let mut f = cfg.get_formatting();
         match &self {
diff --git a/tabled/src/settings/formatting/charset.rs b/tabled/src/settings/formatting/charset.rs
index 48e82b36..1aeef4cc 100644
--- a/tabled/src/settings/formatting/charset.rs
+++ b/tabled/src/settings/formatting/charset.rs
@@ -72,7 +72,7 @@ impl Charset {
 #[derive(Debug, Default, Clone)]
 pub struct CleanCharset;
 
-impl<R, D, C> TableOption<R, D, C> for CleanCharset
+impl<R, D, C> TableOption<R, C, D> for CleanCharset
 where
     R: Records + ExactRecords + RecordsMut<String> + PeekableRecords,
 {
diff --git a/tabled/src/settings/formatting/justification.rs b/tabled/src/settings/formatting/justification.rs
index 5aacd335..5f3fc099 100644
--- a/tabled/src/settings/formatting/justification.rs
+++ b/tabled/src/settings/formatting/justification.rs
@@ -1,6 +1,6 @@
 use crate::{
     grid::{
-        color::AnsiColor,
+        ansi::ANSIBuf,
         config::{ColoredConfig, Entity},
     },
     settings::{CellOption, Color, TableOption},
@@ -85,7 +85,7 @@ use crate::{
 #[derive(Debug, Default, Clone)]
 pub struct Justification {
     c: Option<char>,
-    color: Option<AnsiColor<'static>>,
+    color: Option<ANSIBuf>,
 }
 
 impl Justification {
@@ -106,7 +106,7 @@ impl Justification {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for Justification {
+impl<R, D> TableOption<R, ColoredConfig, D> for Justification {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let c = self.c.unwrap_or(' ');
         let color = self.color;
diff --git a/tabled/src/settings/formatting/tab_size.rs b/tabled/src/settings/formatting/tab_size.rs
index fd8f707f..5abf3ac7 100644
--- a/tabled/src/settings/formatting/tab_size.rs
+++ b/tabled/src/settings/formatting/tab_size.rs
@@ -41,7 +41,7 @@ impl TabSize {
     }
 }
 
-impl<R, D, C> TableOption<R, D, C> for TabSize
+impl<R, D, C> TableOption<R, C, D> for TabSize
 where
     R: Records + ExactRecords + RecordsMut<String> + PeekableRecords,
 {
diff --git a/tabled/src/settings/formatting/trim_strategy.rs b/tabled/src/settings/formatting/trim_strategy.rs
index 11597808..cd7cf4fd 100644
--- a/tabled/src/settings/formatting/trim_strategy.rs
+++ b/tabled/src/settings/formatting/trim_strategy.rs
@@ -111,7 +111,7 @@ impl<R> CellOption<R, ColoredConfig> for TrimStrategy {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for TrimStrategy {
+impl<R, D> TableOption<R, ColoredConfig, D> 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 8e9f8978..eec40d57 100644
--- a/tabled/src/settings/height/cell_height_increase.rs
+++ b/tabled/src/settings/height/cell_height_increase.rs
@@ -72,7 +72,7 @@ where
     }
 }
 
-impl<R, W> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for CellHeightIncrease<W>
+impl<R, W> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for CellHeightIncrease<W>
 where
     W: Measurement<Height>,
     R: Records + ExactRecords + PeekableRecords,
diff --git a/tabled/src/settings/height/cell_height_limit.rs b/tabled/src/settings/height/cell_height_limit.rs
index 38dce248..609386e5 100644
--- a/tabled/src/settings/height/cell_height_limit.rs
+++ b/tabled/src/settings/height/cell_height_limit.rs
@@ -72,7 +72,7 @@ where
     }
 }
 
-impl<R, W> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for CellHeightLimit<W>
+impl<R, W> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for CellHeightLimit<W>
 where
     W: Measurement<Height>,
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
diff --git a/tabled/src/settings/height/height_list.rs b/tabled/src/settings/height/height_list.rs
index 783e7cf6..2f7d657b 100644
--- a/tabled/src/settings/height/height_list.rs
+++ b/tabled/src/settings/height/height_list.rs
@@ -33,7 +33,7 @@ impl FromIterator<usize> for HeightList {
     }
 }
 
-impl<R, C> TableOption<R, CompleteDimensionVecRecords<'_>, C> for HeightList
+impl<R, C> TableOption<R, C, CompleteDimensionVecRecords<'_>> for HeightList
 where
     R: ExactRecords + Records,
 {
diff --git a/tabled/src/settings/height/table_height_increase.rs b/tabled/src/settings/height/table_height_increase.rs
index 082c49e3..5b503414 100644
--- a/tabled/src/settings/height/table_height_increase.rs
+++ b/tabled/src/settings/height/table_height_increase.rs
@@ -44,7 +44,7 @@ impl<W> TableHeightIncrease<W, PriorityNone> {
     }
 }
 
-impl<R, W, P> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig>
+impl<R, W, P> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>>
     for TableHeightIncrease<W, P>
 where
     W: Measurement<Height>,
diff --git a/tabled/src/settings/height/table_height_limit.rs b/tabled/src/settings/height/table_height_limit.rs
index 6c213823..ff33f78d 100644
--- a/tabled/src/settings/height/table_height_limit.rs
+++ b/tabled/src/settings/height/table_height_limit.rs
@@ -45,7 +45,7 @@ impl<W> TableHeightLimit<W, PriorityNone> {
     }
 }
 
-impl<R, W, P> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig>
+impl<R, W, P> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>>
     for TableHeightLimit<W, P>
 where
     W: Measurement<Height>,
diff --git a/tabled/src/settings/highlight/mod.rs b/tabled/src/settings/highlight/mod.rs
index 7a79153e..ca4c8616 100644
--- a/tabled/src/settings/highlight/mod.rs
+++ b/tabled/src/settings/highlight/mod.rs
@@ -7,7 +7,7 @@ use std::collections::HashSet;
 
 use crate::{
     grid::{
-        color::AnsiColor,
+        ansi::ANSIBuf,
         config::{Border as GridBorder, ColoredConfig, Entity, Position, SpannedConfig},
         records::{ExactRecords, Records},
     },
@@ -99,10 +99,10 @@ pub struct Highlight<O> {
 #[derive(Debug)]
 enum HighlightInner {
     Border(GridBorder<char>),
-    // #[cfg(feature = "color")]
-    Color(GridBorder<AnsiColor<'static>>),
-    // #[cfg(feature = "color")]
-    ColoredBorder(GridBorder<char>, GridBorder<AnsiColor<'static>>),
+    // #[cfg(feature = "ansi")]
+    Color(GridBorder<ANSIBuf>),
+    // #[cfg(feature = "ansi")]
+    ColoredBorder(GridBorder<char>, GridBorder<ANSIBuf>),
 }
 
 // todo: Docs testss
@@ -126,7 +126,7 @@ impl<O> Highlight<O> {
     /// Build a new instance of [`Highlight`]
     ///
     /// BE AWARE: if target exceeds boundaries it may panic.
-    // #[cfg(feature = "color")]
+    // #[cfg(feature = "ansi")]
     pub fn color<T, B, L, R>(target: O, border: BorderColor<T, B, L, R>) -> Self {
         let color = border.into_inner();
         let color = color.convert();
@@ -154,7 +154,7 @@ impl<O> Highlight<O> {
     /// Build a new instance of [`Highlight`]
     ///
     /// BE AWARE: if target exceeds boundaries it may panic.
-    // #[cfg(feature = "color")]
+    // #[cfg(feature = "ansi")]
     pub fn colored_border<T, B, L, R>(
         target: O,
         border: Border<T, B, L, R>,
@@ -170,7 +170,7 @@ impl<O> Highlight<O> {
     }
 }
 
-impl<O, R, D> TableOption<R, D, ColoredConfig> for Highlight<O>
+impl<O, R, D> TableOption<R, ColoredConfig, D> for Highlight<O>
 where
     O: Object<R>,
     R: Records + ExactRecords,
@@ -210,7 +210,7 @@ where
 fn set_border_color(
     cfg: &mut SpannedConfig,
     sector: &HashSet<(usize, usize)>,
-    border: &GridBorder<AnsiColor<'static>>,
+    border: &GridBorder<ANSIBuf>,
 ) {
     if sector.is_empty() {
         return;
diff --git a/tabled/src/settings/margin/mod.rs b/tabled/src/settings/margin/mod.rs
index 0f9917c1..6dcc48ee 100644
--- a/tabled/src/settings/margin/mod.rs
+++ b/tabled/src/settings/margin/mod.rs
@@ -28,7 +28,7 @@
 
 use crate::{
     grid::{
-        color::StaticColor,
+        ansi::ANSIStr,
         config::{CompactConfig, CompactMultilineConfig},
         config::{Indent, Sides},
     },
@@ -36,7 +36,7 @@ use crate::{
 };
 
 #[cfg(feature = "std")]
-use crate::grid::{color::AnsiColor, config::ColoredConfig};
+use crate::grid::{ansi::ANSIBuf, config::ColoredConfig};
 
 /// Margin is responsible for a left/right/top/bottom outer indent of a grid.
 ///
@@ -48,7 +48,7 @@ use crate::grid::{color::AnsiColor, config::ColoredConfig};
 ///     .with(Margin::new(1, 1, 1, 1).fill('>', '<', 'V', '^'));
 /// ```
 #[derive(Debug, Clone)]
-pub struct Margin<C = StaticColor> {
+pub struct Margin<C = ANSIStr<'static>> {
     indent: Sides<Indent>,
     colors: Option<Sides<C>>,
 }
@@ -91,9 +91,9 @@ impl<Color> Margin<Color> {
 }
 
 #[cfg(feature = "std")]
-impl<R, D, C> TableOption<R, D, ColoredConfig> for Margin<C>
+impl<R, D, C> TableOption<R, ColoredConfig, D> for Margin<C>
 where
-    C: Into<AnsiColor<'static>> + Clone,
+    C: Into<ANSIBuf> + Clone,
 {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         let indent = self.indent;
@@ -112,9 +112,9 @@ where
     }
 }
 
-impl<R, D, C> TableOption<R, D, CompactConfig> for Margin<C>
+impl<R, D, C> TableOption<R, CompactConfig, D> for Margin<C>
 where
-    C: Into<StaticColor> + Clone,
+    C: Into<ANSIStr<'static>> + Clone,
 {
     fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         *cfg = cfg.set_margin(self.indent);
@@ -127,9 +127,9 @@ where
     }
 }
 
-impl<R, D, C> TableOption<R, D, CompactMultilineConfig> for Margin<C>
+impl<R, D, C> TableOption<R, CompactMultilineConfig, D> for Margin<C>
 where
-    C: Into<StaticColor> + Clone,
+    C: Into<ANSIStr<'static>> + Clone,
 {
     fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
         cfg.set_margin(self.indent);
diff --git a/tabled/src/settings/merge/mod.rs b/tabled/src/settings/merge/mod.rs
index 51fa2bbf..ffc9d205 100644
--- a/tabled/src/settings/merge/mod.rs
+++ b/tabled/src/settings/merge/mod.rs
@@ -34,7 +34,7 @@ impl Merge {
 #[derive(Debug)]
 pub struct MergeDuplicatesVertical;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for MergeDuplicatesVertical
+impl<R, D> TableOption<R, ColoredConfig, D> for MergeDuplicatesVertical
 where
     R: Records + PeekableRecords + ExactRecords,
 {
@@ -118,7 +118,7 @@ where
 #[derive(Debug)]
 pub struct MergeDuplicatesHorizontal;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for MergeDuplicatesHorizontal
+impl<R, D> TableOption<R, ColoredConfig, D> for MergeDuplicatesHorizontal
 where
     R: Records + PeekableRecords + ExactRecords,
 {
diff --git a/tabled/src/settings/modify.rs b/tabled/src/settings/modify.rs
index 4eb63698..0872f7a3 100644
--- a/tabled/src/settings/modify.rs
+++ b/tabled/src/settings/modify.rs
@@ -112,7 +112,7 @@ impl<O, M1> ModifyList<O, M1> {
     }
 }
 
-impl<O, M, R, D, C> TableOption<R, D, C> for ModifyList<O, M>
+impl<O, M, R, D, C> TableOption<R, C, D> for ModifyList<O, M>
 where
     O: Object<R>,
     M: CellOption<R, C> + Clone,
diff --git a/tabled/src/settings/padding/mod.rs b/tabled/src/settings/padding/mod.rs
index f9b9d288..fb9144c7 100644
--- a/tabled/src/settings/padding/mod.rs
+++ b/tabled/src/settings/padding/mod.rs
@@ -37,7 +37,7 @@
 
 use crate::{
     grid::{
-        color::StaticColor,
+        ansi::ANSIStr,
         config::{CompactConfig, CompactMultilineConfig},
         config::{Indent, Sides},
     },
@@ -45,7 +45,7 @@ use crate::{
 };
 
 #[cfg(feature = "std")]
-use crate::grid::{color::AnsiColor, config::ColoredConfig, config::Entity};
+use crate::grid::{ansi::ANSIBuf, config::ColoredConfig, config::Entity};
 #[cfg(feature = "std")]
 use crate::settings::CellOption;
 
@@ -58,7 +58,7 @@ use crate::settings::CellOption;
 /// let table = Table::new(&data).with(Modify::new(Rows::single(0)).with(Padding::new(0, 0, 1, 1).fill('>', '<', '^', 'V')));
 /// ```
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Padding<C = StaticColor> {
+pub struct Padding<C = ANSIStr<'static>> {
     indent: Sides<Indent>,
     colors: Option<Sides<C>>,
 }
@@ -111,7 +111,7 @@ impl<Color> Padding<Color> {
 #[cfg(feature = "std")]
 impl<R, C> CellOption<R, ColoredConfig> for Padding<C>
 where
-    C: Into<AnsiColor<'static>> + Clone,
+    C: Into<ANSIBuf> + Clone,
 {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, entity: Entity) {
         let indent = self.indent;
@@ -131,18 +131,18 @@ where
 }
 
 #[cfg(feature = "std")]
-impl<R, D, C> TableOption<R, D, ColoredConfig> for Padding<C>
+impl<R, D, C> TableOption<R, ColoredConfig, D> for Padding<C>
 where
-    C: Into<AnsiColor<'static>> + Clone,
+    C: Into<ANSIBuf> + Clone,
 {
     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, C> TableOption<R, D, CompactConfig> for Padding<C>
+impl<R, D, C> TableOption<R, CompactConfig, D> for Padding<C>
 where
-    C: Into<StaticColor> + Clone,
+    C: Into<ANSIStr<'static>> + Clone,
 {
     fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         *cfg = cfg.set_padding(self.indent);
@@ -154,9 +154,9 @@ where
     }
 }
 
-impl<R, D, C> TableOption<R, D, CompactMultilineConfig> for Padding<C>
+impl<R, D, C> TableOption<R, CompactMultilineConfig, D> for Padding<C>
 where
-    C: Into<StaticColor> + Clone,
+    C: Into<ANSIStr<'static>> + Clone,
 {
     fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
         cfg.set_padding(self.indent);
diff --git a/tabled/src/settings/panel/footer.rs b/tabled/src/settings/panel/footer.rs
index 8d16481c..a54a9555 100644
--- a/tabled/src/settings/panel/footer.rs
+++ b/tabled/src/settings/panel/footer.rs
@@ -21,7 +21,7 @@ impl<S> Footer<S> {
     }
 }
 
-impl<S, R, D> TableOption<R, D, ColoredConfig> for Footer<S>
+impl<S, R, D> TableOption<R, ColoredConfig, D> for Footer<S>
 where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
diff --git a/tabled/src/settings/panel/header.rs b/tabled/src/settings/panel/header.rs
index e9d398cb..c80cad46 100644
--- a/tabled/src/settings/panel/header.rs
+++ b/tabled/src/settings/panel/header.rs
@@ -21,7 +21,7 @@ impl<S> Header<S> {
     }
 }
 
-impl<S, R, D> TableOption<R, D, ColoredConfig> for Header<S>
+impl<S, R, D> TableOption<R, ColoredConfig, D> for Header<S>
 where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
diff --git a/tabled/src/settings/panel/horizontal_panel.rs b/tabled/src/settings/panel/horizontal_panel.rs
index d5871d72..3593a953 100644
--- a/tabled/src/settings/panel/horizontal_panel.rs
+++ b/tabled/src/settings/panel/horizontal_panel.rs
@@ -18,7 +18,7 @@ impl<S> HorizontalPanel<S> {
     }
 }
 
-impl<S, R, D> TableOption<R, D, ColoredConfig> for HorizontalPanel<S>
+impl<S, R, D> TableOption<R, ColoredConfig, D> for HorizontalPanel<S>
 where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
diff --git a/tabled/src/settings/panel/vertical_panel.rs b/tabled/src/settings/panel/vertical_panel.rs
index ddc0a562..dee2405f 100644
--- a/tabled/src/settings/panel/vertical_panel.rs
+++ b/tabled/src/settings/panel/vertical_panel.rs
@@ -21,7 +21,7 @@ impl<S> VerticalPanel<S> {
     }
 }
 
-impl<S, R, D> TableOption<R, D, ColoredConfig> for VerticalPanel<S>
+impl<S, R, D> TableOption<R, ColoredConfig, D> for VerticalPanel<S>
 where
     S: AsRef<str>,
     R: Records + ExactRecords + Resizable + RecordsMut<String>,
diff --git a/tabled/src/settings/reverse/mod.rs b/tabled/src/settings/reverse/mod.rs
index 8b5807ec..849a7e86 100644
--- a/tabled/src/settings/reverse/mod.rs
+++ b/tabled/src/settings/reverse/mod.rs
@@ -21,7 +21,7 @@ impl Reverse {
     }
 }
 
-impl<R, D, C> TableOption<R, D, C> for Reverse
+impl<R, D, C> TableOption<R, C, D> for Reverse
 where
     R: Resizable + Records + ExactRecords,
 {
diff --git a/tabled/src/settings/rotate/mod.rs b/tabled/src/settings/rotate/mod.rs
index 7f2fbab1..a87a167e 100644
--- a/tabled/src/settings/rotate/mod.rs
+++ b/tabled/src/settings/rotate/mod.rs
@@ -63,7 +63,7 @@ pub enum Rotate {
     Bottom,
 }
 
-impl<R, D, C> TableOption<R, D, C> for Rotate
+impl<R, D, C> TableOption<R, C, D> for Rotate
 where
     R: Records + ExactRecords + Resizable,
 {
diff --git a/tabled/src/settings/settings_list.rs b/tabled/src/settings/settings_list.rs
index 46cfcd15..fc2d9a77 100644
--- a/tabled/src/settings/settings_list.rs
+++ b/tabled/src/settings/settings_list.rs
@@ -53,10 +53,10 @@ where
     }
 }
 
-impl<R, D, C, A, B> TableOption<R, D, C> for Settings<A, B>
+impl<R, D, C, A, B> TableOption<R, C, D> for Settings<A, B>
 where
-    A: TableOption<R, D, C>,
-    B: TableOption<R, D, C>,
+    A: TableOption<R, C, D>,
+    B: TableOption<R, C, D>,
 {
     fn change(self, records: &mut R, cfg: &mut C, dims: &mut D) {
         self.0.change(records, cfg, dims);
@@ -82,7 +82,7 @@ impl<R, C> CellOption<R, C> for EmptySettings {
     fn change(self, _: &mut R, _: &mut C, _: Entity) {}
 }
 
-impl<R, D, C> TableOption<R, D, C> for EmptySettings {
+impl<R, D, C> TableOption<R, C, D> for EmptySettings {
     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 6b8ff486..f64edfc9 100644
--- a/tabled/src/settings/shadow/mod.rs
+++ b/tabled/src/settings/shadow/mod.rs
@@ -28,7 +28,7 @@
 //! [`Table`]: crate::Table
 
 use crate::{
-    grid::color::AnsiColor,
+    grid::ansi::ANSIBuf,
     grid::config::{ColoredConfig, Indent, Offset, Sides},
     settings::{color::Color, TableOption},
 };
@@ -112,7 +112,7 @@ impl Shadow {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for Shadow {
+impl<R, D> TableOption<R, ColoredConfig, D> for Shadow {
     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);
@@ -173,8 +173,8 @@ fn set_margin_offset(cfg: &mut ColoredConfig, size: usize, direction: &Sides<boo
     cfg.set_margin_offset(margin);
 }
 
-fn set_margin_color(cfg: &mut ColoredConfig, color: AnsiColor<'static>, direction: &Sides<bool>) {
-    let mut margin: Sides<Option<AnsiColor<'static>>> = Sides::default();
+fn set_margin_color(cfg: &mut ColoredConfig, color: ANSIBuf, direction: &Sides<bool>) {
+    let mut margin: Sides<Option<ANSIBuf>> = Sides::default();
     if direction.right {
         margin.right = Some(color.clone());
     }
diff --git a/tabled/src/settings/split/mod.rs b/tabled/src/settings/split/mod.rs
index 4cc35bad..becb3c17 100644
--- a/tabled/src/settings/split/mod.rs
+++ b/tabled/src/settings/split/mod.rs
@@ -233,11 +233,11 @@ impl Split {
     }
 }
 
-impl<R, D, Cfg> TableOption<R, D, Cfg> for Split
+impl<R, D, C> TableOption<R, C, D> for Split
 where
     R: Records + ExactRecords + Resizable + PeekableRecords,
 {
-    fn change(self, records: &mut R, _: &mut Cfg, _: &mut D) {
+    fn change(self, records: &mut R, _: &mut C, _: &mut D) {
         // variables
         let Split {
             direction,
diff --git a/tabled/src/settings/style/border_color.rs b/tabled/src/settings/style/border_color.rs
index 162015b1..89ce2167 100644
--- a/tabled/src/settings/style/border_color.rs
+++ b/tabled/src/settings/style/border_color.rs
@@ -237,7 +237,7 @@ where
     }
 }
 
-impl<Data, D, T, B, L, R> TableOption<Data, D, ColoredConfig> for BorderColor<T, B, L, R>
+impl<Data, D, T, B, L, R> TableOption<Data, ColoredConfig, D> for BorderColor<T, B, L, R>
 where
     Data: Records + ExactRecords,
 {
diff --git a/tabled/src/settings/style/border_text.rs b/tabled/src/settings/style/border_text.rs
index 1dd27ab4..f9fc5183 100644
--- a/tabled/src/settings/style/border_text.rs
+++ b/tabled/src/settings/style/border_text.rs
@@ -1,6 +1,6 @@
 use crate::{
     grid::{
-        color::AnsiColor,
+        ansi::ANSIBuf,
         config::{self, ColoredConfig, SpannedConfig},
         dimension::{Dimension, Estimate},
         records::{ExactRecords, Records},
@@ -37,7 +37,7 @@ pub struct LineText<L> {
     // todo: change to T and specify to be As<str>
     text: String,
     offset: Offset,
-    color: Option<AnsiColor<'static>>,
+    color: Option<ANSIBuf>,
     line: L,
 }
 
@@ -57,9 +57,7 @@ impl<Line> LineText<Line> {
             color: None,
         }
     }
-}
 
-impl<Line> LineText<Line> {
     /// Set an offset from which the text will be started.
     pub fn offset(self, offset: impl Into<Offset>) -> Self {
         LineText {
@@ -81,7 +79,7 @@ impl<Line> LineText<Line> {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for LineText<Row>
+impl<R, D> TableOption<R, ColoredConfig, D> for LineText<Row>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -94,7 +92,7 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for LineText<FirstRow>
+impl<R, D> TableOption<R, ColoredConfig, D> for LineText<FirstRow>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -106,7 +104,7 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for LineText<LastRow>
+impl<R, D> TableOption<R, ColoredConfig, D> for LineText<LastRow>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -119,7 +117,7 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for LineText<Column>
+impl<R, D> TableOption<R, ColoredConfig, D> for LineText<Column>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -132,7 +130,7 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for LineText<FirstColumn>
+impl<R, D> TableOption<R, ColoredConfig, D> for LineText<FirstColumn>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -144,7 +142,7 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for LineText<LastColumn>
+impl<R, D> TableOption<R, ColoredConfig, D> for LineText<LastColumn>
 where
     R: Records + ExactRecords,
     for<'a> &'a R: Records,
@@ -163,7 +161,7 @@ fn set_horizontal_chars<D: Dimension>(
     offset: Offset,
     line: usize,
     text: &str,
-    color: &Option<AnsiColor<'static>>,
+    color: &Option<ANSIBuf>,
     shape: (usize, usize),
 ) {
     let (_, count_columns) = shape;
@@ -249,7 +247,7 @@ fn set_vertical_chars<D>(
     offset: Offset,
     line: usize,
     text: &str,
-    color: &Option<AnsiColor<'static>>,
+    color: &Option<ANSIBuf>,
     shape: (usize, usize),
 ) where
     D: Dimension,
@@ -380,7 +378,7 @@ fn change_horizontal_chars<R, D>(
     line: usize,
     text: String,
     offset: Offset,
-    color: Option<AnsiColor<'static>>,
+    color: Option<ANSIBuf>,
 ) where
     R: Records + ExactRecords,
     for<'a> D: Estimate<&'a R, ColoredConfig>,
@@ -398,7 +396,7 @@ fn change_vertical_chars<R, D>(
     line: usize,
     text: String,
     offset: Offset,
-    color: Option<AnsiColor<'static>>,
+    color: Option<ANSIBuf>,
 ) where
     R: Records + ExactRecords,
     for<'a> D: Estimate<&'a R, ColoredConfig>,
diff --git a/tabled/src/settings/style/builder.rs b/tabled/src/settings/style/builder.rs
index 43c9b0ae..eaa60c87 100644
--- a/tabled/src/settings/style/builder.rs
+++ b/tabled/src/settings/style/builder.rs
@@ -1426,7 +1426,7 @@ impl<T, B, L, R, H, const HN: usize, const VN: usize> Style<T, B, L, R, H, On, H
 
 #[cfg(feature = "std")]
 impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
-    TableOption<Data, Dims, ColoredConfig> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
+    TableOption<Data, ColoredConfig, Dims> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
 {
     fn change(self, _: &mut Data, cfg: &mut ColoredConfig, _: &mut Dims) {
         cfg_clear_borders(cfg);
@@ -1436,7 +1436,7 @@ impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
 }
 
 impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
-    TableOption<Data, Dims, CompactConfig> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
+    TableOption<Data, CompactConfig, Dims> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
 {
     fn change(self, _: &mut Data, cfg: &mut CompactConfig, _: &mut Dims) {
         *cfg = cfg.set_borders(self.borders);
@@ -1444,7 +1444,7 @@ impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
 }
 
 impl<T, B, L, R, H, V, Data, Dims, const HSIZE: usize, const VSIZE: usize>
-    TableOption<Data, Dims, CompactMultilineConfig> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
+    TableOption<Data, CompactMultilineConfig, Dims> for Style<T, B, L, R, H, V, HSIZE, VSIZE>
 {
     fn change(self, _: &mut Data, cfg: &mut CompactMultilineConfig, _: &mut Dims) {
         cfg.set_borders(self.borders);
diff --git a/tabled/src/settings/style/mod.rs b/tabled/src/settings/style/mod.rs
index 91e3654c..f8fec995 100644
--- a/tabled/src/settings/style/mod.rs
+++ b/tabled/src/settings/style/mod.rs
@@ -133,20 +133,20 @@ use crate::settings::TableOption;
 use crate::grid::config::ColoredConfig;
 
 #[cfg(feature = "std")]
-impl<R, D> TableOption<R, D, ColoredConfig> for Borders<char> {
+impl<R, D> TableOption<R, ColoredConfig, D> for Borders<char> {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         cfg_clear_borders(cfg);
         cfg.set_borders(self);
     }
 }
 
-impl<R, D> TableOption<R, D, CompactConfig> for Borders<char> {
+impl<R, D> TableOption<R, CompactConfig, D> for Borders<char> {
     fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         *cfg = cfg.set_borders(self);
     }
 }
 
-impl<R, D> TableOption<R, D, CompactMultilineConfig> for Borders<char> {
+impl<R, D> TableOption<R, CompactMultilineConfig, D> for Borders<char> {
     fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
         cfg.set_borders(self);
     }
diff --git a/tabled/src/settings/style/span_border_correction.rs b/tabled/src/settings/style/span_border_correction.rs
index 665a1278..b5837efc 100644
--- a/tabled/src/settings/style/span_border_correction.rs
+++ b/tabled/src/settings/style/span_border_correction.rs
@@ -76,7 +76,7 @@ use crate::{
 #[derive(Debug)]
 pub struct BorderSpanCorrection;
 
-impl<R, D> TableOption<R, D, ColoredConfig> for BorderSpanCorrection
+impl<R, D> TableOption<R, ColoredConfig, D> for BorderSpanCorrection
 where
     R: Records + ExactRecords,
 {
diff --git a/tabled/src/settings/table_option.rs b/tabled/src/settings/table_option.rs
index 54711054..02fb9562 100644
--- a/tabled/src/settings/table_option.rs
+++ b/tabled/src/settings/table_option.rs
@@ -3,10 +3,8 @@ use crate::grid::config::Entity;
 /// A trait which is responsible for configuration of a [`Table`].
 ///
 /// [`Table`]: crate::Table
-pub trait TableOption<R, D, C> {
-    // todo: change the method or generic order to match :)
-
-    /// The function allows modification of records and a grid configuration.
+pub trait TableOption<R, C, D> {
+    /// The function modificaties of records and a grid configuration.
     fn change(self, records: &mut R, cfg: &mut C, dimension: &mut D);
 
     /// A hint whether an [`TableOption`] is going to change table layout.
@@ -49,9 +47,9 @@ pub trait TableOption<R, D, C> {
 //     Some(vec![Entity::Global])
 // }
 
-impl<T, R, D, C> TableOption<R, D, C> for &[T]
+impl<T, R, C, D> TableOption<R, C, D> for &[T]
 where
-    for<'a> &'a T: TableOption<R, D, C>,
+    for<'a> &'a T: TableOption<R, C, D>,
 {
     fn change(self, records: &mut R, cfg: &mut C, dimension: &mut D) {
         for opt in self {
@@ -61,9 +59,9 @@ where
 }
 
 #[cfg(feature = "std")]
-impl<T, R, D, C> TableOption<R, D, C> for Vec<T>
+impl<T, R, D, C> TableOption<R, C, D> for Vec<T>
 where
-    T: TableOption<R, D, C>,
+    T: TableOption<R, C, D>,
 {
     fn change(self, records: &mut R, cfg: &mut C, dimension: &mut D) {
         for opt in self {
diff --git a/tabled/src/settings/themes/colorization.rs b/tabled/src/settings/themes/colorization.rs
index 7333eb8d..c0461a94 100644
--- a/tabled/src/settings/themes/colorization.rs
+++ b/tabled/src/settings/themes/colorization.rs
@@ -1,6 +1,6 @@
 use crate::{
     grid::{
-        color::AnsiColor,
+        ansi::ANSIBuf,
         config::{ColoredConfig, Entity, Sides},
         records::{ExactRecords, Records},
     },
@@ -232,7 +232,7 @@ impl Colorization {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for Colorization
+impl<R, D> TableOption<R, ColoredConfig, D> for Colorization
 where
     R: Records + ExactRecords,
 {
@@ -337,7 +337,7 @@ fn colorize_diogonals(
 }
 
 fn colorize_entity(color: &Color, pos: Entity, cfg: &mut ColoredConfig) {
-    let ansi_color = AnsiColor::from(color.clone());
+    let ansi_color = ANSIBuf::from(color.clone());
     let _ = cfg.set_color(pos, ansi_color.clone());
     cfg.set_justification_color(pos, Some(ansi_color.clone()));
     cfg.set_padding_color(
@@ -366,7 +366,7 @@ impl<O> ExactColorization<O> {
     }
 }
 
-impl<R, D, O> TableOption<R, D, ColoredConfig> for ExactColorization<O>
+impl<R, D, O> TableOption<R, ColoredConfig, D> for ExactColorization<O>
 where
     O: Object<R>,
 {
diff --git a/tabled/src/settings/themes/column_names.rs b/tabled/src/settings/themes/column_names.rs
index 33b8e756..871e398a 100644
--- a/tabled/src/settings/themes/column_names.rs
+++ b/tabled/src/settings/themes/column_names.rs
@@ -223,7 +223,7 @@ impl ColumnNames {
     }
 }
 
-impl TableOption<VecRecords<CellInfo<String>>, CompleteDimensionVecRecords<'_>, ColoredConfig>
+impl TableOption<VecRecords<CellInfo<String>>, ColoredConfig, CompleteDimensionVecRecords<'_>>
     for ColumnNames
 {
     fn change(
diff --git a/tabled/src/settings/themes/theme.rs b/tabled/src/settings/themes/theme.rs
index cc283c3b..ef60195e 100644
--- a/tabled/src/settings/themes/theme.rs
+++ b/tabled/src/settings/themes/theme.rs
@@ -14,7 +14,6 @@ use std::iter::FromIterator;
 
 use crate::{
     grid::{
-        color::AnsiColor,
         config::{
             AlignmentHorizontal, AlignmentVertical, Border, Borders, ColoredConfig, CompactConfig,
             CompactMultilineConfig, HorizontalLine, VerticalLine,
@@ -493,7 +492,7 @@ impl From<Borders<char>> for Theme {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for Theme
+impl<R, D> TableOption<R, ColoredConfig, D> for Theme
 where
     R: Records + Resizable + ExactRecords + PeekableRecords + RecordsMut<String>,
 {
@@ -518,13 +517,13 @@ where
     }
 }
 
-impl<R, D> TableOption<R, D, CompactConfig> for Theme {
+impl<R, D> TableOption<R, CompactConfig, D> for Theme {
     fn change(self, _: &mut R, cfg: &mut CompactConfig, _: &mut D) {
         *cfg = cfg.set_borders(self.border.chars);
     }
 }
 
-impl<R, D> TableOption<R, D, CompactMultilineConfig> for Theme {
+impl<R, D> TableOption<R, CompactMultilineConfig, D> for Theme {
     fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
         cfg.set_borders(self.border.chars);
     }
@@ -541,7 +540,7 @@ impl<T, B, L, R, H, V, const HSIZE: usize, const VSIZE: usize>
 impl From<ColoredConfig> for Theme {
     fn from(cfg: ColoredConfig) -> Self {
         let borders = *cfg.get_borders();
-        let colors = borders_convert_ansi_color_to_color(cfg.get_color_borders().clone());
+        let colors = cfg.get_color_borders().clone().convert_into();
         let horizontals = cfg.get_horizontal_lines().into_iter().collect();
         let verticals = cfg.get_vertical_lines().into_iter().collect();
 
@@ -592,46 +591,6 @@ impl Layout {
     }
 }
 
-fn borders_convert_ansi_color_to_color(b: Borders<AnsiColor<'static>>) -> Borders<Color> {
-    Borders {
-        top: b.top.map(Color::from),
-        top_left: b.top_left.map(Color::from),
-        top_right: b.top_right.map(Color::from),
-        top_intersection: b.top_intersection.map(Color::from),
-        bottom: b.bottom.map(Color::from),
-        bottom_left: b.bottom_left.map(Color::from),
-        bottom_right: b.bottom_right.map(Color::from),
-        bottom_intersection: b.bottom_intersection.map(Color::from),
-        horizontal: b.horizontal.map(Color::from),
-        vertical: b.vertical.map(Color::from),
-        intersection: b.intersection.map(Color::from),
-        left: b.left.map(Color::from),
-        left_intersection: b.left_intersection.map(Color::from),
-        right: b.right.map(Color::from),
-        right_intersection: b.right_intersection.map(Color::from),
-    }
-}
-
-fn borders_convert_color_to_ansi_color(b: Borders<Color>) -> Borders<AnsiColor<'static>> {
-    Borders {
-        top: b.top.map(AnsiColor::from),
-        top_left: b.top_left.map(AnsiColor::from),
-        top_right: b.top_right.map(AnsiColor::from),
-        top_intersection: b.top_intersection.map(AnsiColor::from),
-        bottom: b.bottom.map(AnsiColor::from),
-        bottom_left: b.bottom_left.map(AnsiColor::from),
-        bottom_right: b.bottom_right.map(AnsiColor::from),
-        bottom_intersection: b.bottom_intersection.map(AnsiColor::from),
-        horizontal: b.horizontal.map(AnsiColor::from),
-        vertical: b.vertical.map(AnsiColor::from),
-        intersection: b.intersection.map(AnsiColor::from),
-        left: b.left.map(AnsiColor::from),
-        left_intersection: b.left_intersection.map(AnsiColor::from),
-        right: b.right.map(AnsiColor::from),
-        right_intersection: b.right_intersection.map(AnsiColor::from),
-    }
-}
-
 fn cfg_clear_borders(cfg: &mut ColoredConfig) {
     cfg.remove_borders();
     cfg.remove_borders_colors();
@@ -645,7 +604,7 @@ fn cfg_set_borders(cfg: &mut ColoredConfig, border: TableBorders) {
     cfg.set_borders(border.chars);
 
     if !border.colors.is_empty() {
-        cfg.set_borders_color(borders_convert_color_to_ansi_color(border.colors));
+        cfg.set_borders_color(border.colors.convert_into());
     }
 }
 
diff --git a/tabled/src/settings/width/justify.rs b/tabled/src/settings/width/justify.rs
index f1a06f60..91b2f79f 100644
--- a/tabled/src/settings/width/justify.rs
+++ b/tabled/src/settings/width/justify.rs
@@ -73,7 +73,7 @@ impl Justify<Min> {
     }
 }
 
-impl<R, D, W> TableOption<R, D, ColoredConfig> for Justify<W>
+impl<R, D, W> TableOption<R, ColoredConfig, D> for Justify<W>
 where
     W: Measurement<Width>,
     R: Records + ExactRecords + PeekableRecords + RecordsMut<String>,
diff --git a/tabled/src/settings/width/min_width.rs b/tabled/src/settings/width/min_width.rs
index 711f95a9..6b5b97a9 100644
--- a/tabled/src/settings/width/min_width.rs
+++ b/tabled/src/settings/width/min_width.rs
@@ -136,7 +136,7 @@ where
     }
 }
 
-impl<W, P, R> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for MinWidth<W, P>
+impl<W, P, R> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for MinWidth<W, P>
 where
     W: Measurement<Width>,
     P: Peaker,
diff --git a/tabled/src/settings/width/truncate.rs b/tabled/src/settings/width/truncate.rs
index 6c1a29ce..83a05baa 100644
--- a/tabled/src/settings/width/truncate.rs
+++ b/tabled/src/settings/width/truncate.rs
@@ -45,7 +45,7 @@ pub struct Truncate<'a, W = usize, P = PriorityNone> {
     multiline: bool,
     _priority: PhantomData<P>,
 }
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
 struct TruncateSuffix<'a> {
     text: Cow<'a, str>,
@@ -53,7 +53,7 @@ struct TruncateSuffix<'a> {
     try_color: bool,
 }
 
-#[cfg(not(feature = "color"))]
+#[cfg(not(feature = "ansi"))]
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
 struct TruncateSuffix<'a> {
     text: Cow<'a, str>,
@@ -65,7 +65,7 @@ impl Default for TruncateSuffix<'_> {
         Self {
             text: Cow::default(),
             limit: SuffixLimit::Cut,
-            #[cfg(feature = "color")]
+            #[cfg(feature = "ansi")]
             try_color: false,
         }
     }
@@ -141,7 +141,7 @@ impl<'a, W, P> Truncate<'a, W, P> {
         }
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     /// Sets a optional logic to try to colorize a suffix.
     pub fn suffix_try_color(self, color: bool) -> Truncate<'a, W, P> {
         let mut suff = self.suffix.unwrap_or_default();
@@ -271,11 +271,11 @@ fn make_text_truncated<'a>(
 }
 
 fn need_suffix_color_preservation(_suffix: &Option<TruncateSuffix<'_>>) -> bool {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         false
     }
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         _suffix.as_ref().map_or(false, |s| s.try_color)
     }
@@ -300,7 +300,7 @@ fn make_suffix<'a>(suffix: &'a TruncateSuffix<'_>, width: usize) -> (Cow<'a, str
     }
 }
 
-impl<W, P, R> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for Truncate<'_, W, P>
+impl<W, P, R> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for Truncate<'_, W, P>
 where
     W: Measurement<Width>,
     P: Peaker,
@@ -327,7 +327,7 @@ where
         let suffix = self.suffix.as_ref().map(|s| TruncateSuffix {
             text: Cow::Borrowed(&s.text),
             limit: s.limit,
-            #[cfg(feature = "color")]
+            #[cfg(feature = "ansi")]
             try_color: s.try_color,
         });
 
@@ -388,7 +388,7 @@ fn truncate_text<'a>(
         return content;
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         if _suffix_color {
             if let Some(block) = ansi_str::get_blocks(text).last() {
@@ -418,7 +418,7 @@ fn truncate_text<'a>(
         }
     }
 
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         let mut content = content.into_owned();
         content.push_str(suffix);
diff --git a/tabled/src/settings/width/util.rs b/tabled/src/settings/width/util.rs
index 1f4ea78b..4cdf0491 100644
--- a/tabled/src/settings/width/util.rs
+++ b/tabled/src/settings/width/util.rs
@@ -36,7 +36,7 @@ fn get_table_total_width(list: &[usize], cfg: &SpannedConfig) -> usize {
 ///
 /// BE AWARE: width is expected to be in bytes.
 pub(crate) fn cut_str(s: &str, width: usize) -> Cow<'_, str> {
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         const REPLACEMENT: char = '\u{FFFD}';
 
@@ -53,7 +53,7 @@ pub(crate) fn cut_str(s: &str, width: usize) -> Cow<'_, str> {
         buf
     }
 
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         cut_str_basic(s, width)
     }
@@ -62,7 +62,7 @@ pub(crate) fn cut_str(s: &str, width: usize) -> Cow<'_, str> {
 /// The function cuts the string to a specific width.
 ///
 /// BE AWARE: width is expected to be in bytes.
-#[cfg(not(feature = "color"))]
+#[cfg(not(feature = "ansi"))]
 pub(crate) fn cut_str_basic(s: &str, width: usize) -> Cow<'_, str> {
     const REPLACEMENT: char = '\u{FFFD}';
 
@@ -113,7 +113,7 @@ pub(crate) fn split_at_pos(s: &str, pos: usize) -> (usize, usize, usize) {
 /// <https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>
 ///
 /// The function is based on Dan Davison <https://github.com/dandavison> delta <https://github.com/dandavison/delta> ansi library.
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 pub(crate) fn strip_osc(text: &str) -> (String, Option<String>) {
     #[derive(Debug)]
     enum ExtractOsc8HyperlinkState {
@@ -176,7 +176,7 @@ mod tests {
 
     use crate::grid::util::string::string_width;
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     use owo_colors::{colors::Yellow, OwoColorize};
 
     #[test]
@@ -217,7 +217,7 @@ mod tests {
         assert_eq!(cut_str("🇻🇬", 4), "🇻🇬");
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn strip_color_test() {
         let numbers = "123456".red().on_bright_black().to_string();
@@ -257,7 +257,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     fn test_color_strip() {
         let s = "Collored string"
             .fg::<Yellow>()
@@ -271,7 +271,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     fn test_srip_osc() {
         assert_eq!(
             strip_osc("just a string here"),
@@ -303,7 +303,7 @@ mod tests {
             (String::default(), Some(String::from("https://gitlab.com/finestructure/swiftpackageindex-builder/-/pipelines/1054655982")))
         );
 
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         fn build_link_prefix_suffix(url: &str) -> String {
             // https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
             let osc8 = "\x1b]8;;";
diff --git a/tabled/src/settings/width/width_list.rs b/tabled/src/settings/width/width_list.rs
index 08ed418c..15572974 100644
--- a/tabled/src/settings/width/width_list.rs
+++ b/tabled/src/settings/width/width_list.rs
@@ -31,7 +31,7 @@ impl FromIterator<usize> for WidthList {
     }
 }
 
-impl<R, C> TableOption<R, CompleteDimensionVecRecords<'_>, C> for WidthList
+impl<R, C> TableOption<R, C, CompleteDimensionVecRecords<'_>> for WidthList
 where
     R: Records,
 {
diff --git a/tabled/src/settings/width/wrap.rs b/tabled/src/settings/width/wrap.rs
index 640fbc38..8146edd8 100644
--- a/tabled/src/settings/width/wrap.rs
+++ b/tabled/src/settings/width/wrap.rs
@@ -100,7 +100,7 @@ impl Wrap<(), ()> {
     }
 }
 
-impl<W, P, R> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for Wrap<W, P>
+impl<W, P, R> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for Wrap<W, P>
 where
     W: Measurement<Width>,
     P: Peaker,
@@ -194,7 +194,7 @@ where
     widths
 }
 
-#[cfg(not(feature = "color"))]
+#[cfg(not(feature = "ansi"))]
 pub(crate) fn wrap_text(text: &str, width: usize, keep_words: bool) -> String {
     if width == 0 {
         return String::new();
@@ -207,7 +207,7 @@ pub(crate) fn wrap_text(text: &str, width: usize, keep_words: bool) -> String {
     }
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 pub(crate) fn wrap_text(text: &str, width: usize, keep_words: bool) -> String {
     use super::util::strip_osc;
 
@@ -225,7 +225,7 @@ pub(crate) fn wrap_text(text: &str, width: usize, keep_words: bool) -> String {
     }
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 fn build_link_prefix_suffix(url: Option<String>) -> (String, String) {
     match url {
         Some(url) => {
@@ -239,7 +239,7 @@ fn build_link_prefix_suffix(url: Option<String>) -> (String, String) {
     }
 }
 
-#[cfg(not(feature = "color"))]
+#[cfg(not(feature = "ansi"))]
 fn chunks(s: &str, width: usize) -> Vec<String> {
     if width == 0 {
         return Vec::new();
@@ -275,7 +275,7 @@ fn chunks(s: &str, width: usize) -> Vec<String> {
     list
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 fn chunks(s: &str, width: usize, prefix: &str, suffix: &str) -> Vec<String> {
     use std::fmt::Write;
 
@@ -360,7 +360,7 @@ fn chunks(s: &str, width: usize, prefix: &str, suffix: &str) -> Vec<String> {
     list
 }
 
-#[cfg(not(feature = "color"))]
+#[cfg(not(feature = "ansi"))]
 fn split_keeping_words(s: &str, width: usize, sep: &str) -> String {
     const REPLACEMENT: char = '\u{FFFD}';
 
@@ -439,7 +439,7 @@ fn split_keeping_words(s: &str, width: usize, sep: &str) -> String {
     lines.join(sep)
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 fn split_keeping_words(text: &str, width: usize, prefix: &str, suffix: &str) -> String {
     if text.is_empty() || width == 0 {
         return String::new();
@@ -480,7 +480,7 @@ fn split_keeping_words(text: &str, width: usize, prefix: &str, suffix: &str) ->
     buf.into_string()
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 mod parsing {
     use ansi_str::{AnsiBlock, AnsiBlockIter, Style};
     use std::fmt::Write;
@@ -875,10 +875,10 @@ mod tests {
 
     #[test]
     fn split_test() {
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         let split = |text, width| chunks(text, width).join("\n");
 
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         let split = |text, width| chunks(text, width, "", "").join("\n");
 
         assert_eq!(split("123456", 0), "");
@@ -902,10 +902,10 @@ mod tests {
     #[test]
     fn chunks_test() {
         #[allow(clippy::redundant_closure)]
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         let chunks = |text, width| chunks(text, width);
 
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         let chunks = |text, width| chunks(text, width, "", "");
 
         assert_eq!(chunks("123456", 0), [""; 0]);
@@ -919,7 +919,7 @@ mod tests {
         assert_eq!(chunks("😳😳😳😳😳", 3), ["😳�", "😳�", "😳"]);
     }
 
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     #[test]
     fn split_by_line_keeping_words_test() {
         let split_keeping_words = |text, width| split_keeping_words(text, width, "\n");
@@ -933,10 +933,10 @@ mod tests {
         assert_eq!(split_keeping_words("111 234 1", 4), "111 \n234 \n1   ");
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn split_by_line_keeping_words_test() {
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         let split_keeping_words = |text, width| split_keeping_words(text, width, "", "");
 
         assert_eq!(split_keeping_words("123456", 1), "1\n2\n3\n4\n5\n6");
@@ -948,13 +948,13 @@ mod tests {
         assert_eq!(split_keeping_words("111 234 1", 4), "111 \n234 \n1   ");
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn split_by_line_keeping_words_color_test() {
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         let split_keeping_words = |text, width| split_keeping_words(text, width, "", "");
 
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         let split_keeping_words = |text, width| split_keeping_words(text, width, "\n");
 
         let text = "\u{1b}[36mJapanese “vacancy” button\u{1b}[0m";
@@ -963,15 +963,15 @@ mod tests {
         assert_eq!(split_keeping_words(text, 1), "\u{1b}[36mJ\u{1b}[39m\n\u{1b}[36ma\u{1b}[39m\n\u{1b}[36mp\u{1b}[39m\n\u{1b}[36ma\u{1b}[39m\n\u{1b}[36mn\u{1b}[39m\n\u{1b}[36me\u{1b}[39m\n\u{1b}[36ms\u{1b}[39m\n\u{1b}[36me\u{1b}[39m\n\u{1b}[36m \u{1b}[39m\n\u{1b}[36m“\u{1b}[39m\n\u{1b}[36mv\u{1b}[39m\n\u{1b}[36ma\u{1b}[39m\n\u{1b}[36mc\u{1b}[39m\n\u{1b}[36ma\u{1b}[39m\n\u{1b}[36mn\u{1b}[39m\n\u{1b}[36mc\u{1b}[39m\n\u{1b}[36my\u{1b}[39m\n\u{1b}[36m”\u{1b}[39m\n\u{1b}[36m \u{1b}[39m\n\u{1b}[36mb\u{1b}[39m\n\u{1b}[36mu\u{1b}[39m\n\u{1b}[36mt\u{1b}[39m\n\u{1b}[36mt\u{1b}[39m\n\u{1b}[36mo\u{1b}[39m\n\u{1b}[36mn\u{1b}[39m");
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn split_by_line_keeping_words_color_2_test() {
         use ansi_str::AnsiStr;
 
-        #[cfg(feature = "color")]
+        #[cfg(feature = "ansi")]
         let split_keeping_words = |text, width| split_keeping_words(text, width, "", "");
 
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         let split_keeping_words = |text, width| split_keeping_words(text, width, "\n");
 
         let text = "\u{1b}[37mTigre Ecuador   OMYA Andina     3824909999      Calcium carbonate       Colombia\u{1b}[0m";
@@ -1113,7 +1113,7 @@ mod tests {
         )
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn split_by_line_keeping_words_color_3_test() {
         let split = |text, width| split_keeping_words(text, width, "", "");
@@ -1142,7 +1142,7 @@ mod tests {
         );
     }
 
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     #[test]
     fn split_keeping_words_4_test() {
         let split_keeping_words = |text, width| split_keeping_words(text, width, "\n");
@@ -1151,19 +1151,19 @@ mod tests {
         assert_eq!(split_keeping_words("12345678", 2,), "12\n34\n56\n78");
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn split_keeping_words_4_test() {
         let split_keeping_words = |text, width| split_keeping_words(text, width, "", "");
 
-        #[cfg(not(feature = "color"))]
+        #[cfg(not(feature = "ansi"))]
         let split_keeping_words = |text, width| split_keeping_words(text, width, "\n");
 
         assert_eq!(split_keeping_words("12345678", 3,), "123\n456\n78 ");
         assert_eq!(split_keeping_words("12345678", 2,), "12\n34\n56\n78");
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn chunks_test_with_prefix_and_suffix() {
         assert_eq!(chunks("123456", 0, "^", "$"), ["^$"; 0]);
@@ -1189,7 +1189,7 @@ mod tests {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn split_by_line_keeping_words_test_with_prefix_and_suffix() {
         assert_eq!(
@@ -1211,7 +1211,7 @@ mod tests {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn split_by_line_keeping_words_color_2_test_with_prefix_and_suffix() {
         use ansi_str::AnsiStr;
@@ -1355,7 +1355,7 @@ mod tests {
         )
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn chunks_wrap_2() {
         let text = "\u{1b}[30mDebian\u{1b}[0m\u{1b}[31mDebian\u{1b}[0m\u{1b}[32mDebian\u{1b}[0m\u{1b}[33mDebian\u{1b}[0m\u{1b}[34mDebian\u{1b}[0m\u{1b}[35mDebian\u{1b}[0m\u{1b}[36mDebian\u{1b}[0m\u{1b}[37mDebian\u{1b}[0m\u{1b}[40mDebian\u{1b}[0m\u{1b}[41mDebian\u{1b}[0m\u{1b}[42mDebian\u{1b}[0m\u{1b}[43mDebian\u{1b}[0m\u{1b}[44mDebian\u{1b}[0m";
@@ -1369,7 +1369,7 @@ mod tests {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn chunks_wrap_3() {
         let text = "\u{1b}[37mCreate bytes from the \u{1b}[0m\u{1b}[7;34marg\u{1b}[0m\u{1b}[37muments.\u{1b}[0m";
@@ -1383,7 +1383,7 @@ mod tests {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn chunks_wrap_3_keeping_words() {
         let text = "\u{1b}[37mCreate bytes from the \u{1b}[0m\u{1b}[7;34marg\u{1b}[0m\u{1b}[37muments.\u{1b}[0m";
@@ -1394,7 +1394,7 @@ mod tests {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn chunks_wrap_4() {
         let text = "\u{1b}[37mReturns the floor of a number (l\u{1b}[0m\u{1b}[41;37marg\u{1b}[0m\u{1b}[37mest integer less than or equal to that number).\u{1b}[0m";
@@ -1415,7 +1415,7 @@ mod tests {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn chunks_wrap_4_keeping_words() {
         let text = "\u{1b}[37mReturns the floor of a number (l\u{1b}[0m\u{1b}[41;37marg\u{1b}[0m\u{1b}[37mest integer less than or equal to that number).\u{1b}[0m";
diff --git a/tabled/src/tables/compact.rs b/tabled/src/tables/compact.rs
index 37b07dfa..231ca078 100644
--- a/tabled/src/tables/compact.rs
+++ b/tabled/src/tables/compact.rs
@@ -163,7 +163,7 @@ impl<I, D> CompactTable<I, D> {
     /// With is a generic function which applies options to the [`CompactTable`].
     pub fn with<O>(mut self, option: O) -> Self
     where
-        for<'a> O: TableOption<IterRecords<&'a I>, D, CompactConfig>,
+        for<'a> O: TableOption<IterRecords<&'a I>, CompactConfig, D>,
     {
         let mut records = IterRecords::new(&self.records, self.count_columns, self.count_rows);
         option.change(&mut records, &mut self.cfg, &mut self.dims);
@@ -312,7 +312,7 @@ const fn create_config() -> CompactConfig {
         .set_borders(Style::ascii().get_borders())
 }
 
-impl<R, D> TableOption<R, D, CompactConfig> for CompactConfig {
+impl<R, D> TableOption<R, CompactConfig, D> for CompactConfig {
     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 b12d662e..303cc867 100644
--- a/tabled/src/tables/iter.rs
+++ b/tabled/src/tables/iter.rs
@@ -87,7 +87,7 @@ impl<I> IterTable<I> {
     /// With is a generic function which applies options to the [`IterTable`].
     pub fn with<O>(mut self, option: O) -> Self
     where
-        for<'a> O: TableOption<IterRecords<&'a I>, StaticDimension, CompactConfig>,
+        for<'a> O: TableOption<IterRecords<&'a I>, CompactConfig, StaticDimension>,
     {
         let count_columns = self.table.count_columns.unwrap_or(0);
         let mut records = IterRecords::new(&self.records, count_columns, self.table.count_rows);
diff --git a/tabled/src/tables/table.rs b/tabled/src/tables/table.rs
index 5ec44822..cc8c484b 100644
--- a/tabled/src/tables/table.rs
+++ b/tabled/src/tables/table.rs
@@ -173,8 +173,8 @@ impl Table {
     where
         for<'a> O: TableOption<
             VecRecords<CellInfo<String>>,
-            CompleteDimensionVecRecords<'a>,
             ColoredConfig,
+            CompleteDimensionVecRecords<'a>,
         >,
     {
         let reastimation_hint = option.hint_change();
@@ -347,25 +347,25 @@ impl From<Table> for Builder {
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for CompactConfig {
+impl<R, D> TableOption<R, ColoredConfig, D> 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 {
+impl<R, D> TableOption<R, ColoredConfig, D> for ColoredConfig {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         *cfg = self;
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for SpannedConfig {
+impl<R, D> TableOption<R, ColoredConfig, D> for SpannedConfig {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         *cfg.deref_mut() = self;
     }
 }
 
-impl<R, D> TableOption<R, D, ColoredConfig> for &SpannedConfig {
+impl<R, D> TableOption<R, ColoredConfig, D> for &SpannedConfig {
     fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
         *cfg.deref_mut() = self.clone();
     }
diff --git a/tabled/src/tables/table_pool.rs b/tabled/src/tables/table_pool.rs
index 00d18aa0..8a7a93a0 100644
--- a/tabled/src/tables/table_pool.rs
+++ b/tabled/src/tables/table_pool.rs
@@ -173,7 +173,7 @@ impl PoolTable {
     /// ```
     pub fn with<O>(&mut self, option: O) -> &mut Self
     where
-        O: TableOption<EmptyRecords, PoolTableDimension, CompactMultilineConfig>,
+        O: TableOption<EmptyRecords, CompactMultilineConfig, PoolTableDimension>,
     {
         let mut records = EmptyRecords::default();
         option.change(&mut records, &mut self.config, &mut self.dims);
@@ -225,13 +225,13 @@ fn configure_grid() -> CompactMultilineConfig {
     cfg
 }
 
-impl<R, C> TableOption<R, PoolTableDimension, C> for PoolTableDimension {
+impl<R, C> TableOption<R, C, PoolTableDimension> for PoolTableDimension {
     fn change(self, _: &mut R, _: &mut C, dimension: &mut PoolTableDimension) {
         *dimension = self;
     }
 }
 
-impl<R, D> TableOption<R, D, CompactMultilineConfig> for CompactMultilineConfig {
+impl<R, D> TableOption<R, CompactMultilineConfig, D> for CompactMultilineConfig {
     fn change(self, _: &mut R, config: &mut CompactMultilineConfig, _: &mut D) {
         *config = self;
     }
@@ -243,7 +243,7 @@ mod print {
     use crate::{
         builder::Builder,
         grid::{
-            color::StaticColor,
+            ansi::ANSIStr,
             config::{
                 AlignmentHorizontal, AlignmentVertical, Border, Borders, ColoredConfig,
                 CompactMultilineConfig, Indent, Offset, Sides,
@@ -729,7 +729,7 @@ mod print {
         buf
     }
 
-    fn print_chars(buf: &mut String, c: char, color: Option<StaticColor>, width: usize) {
+    fn print_chars(buf: &mut String, c: char, color: Option<ANSIStr<'static>>, width: usize) {
         match color {
             Some(color) => {
                 buf.push_str(color.get_prefix());
@@ -740,7 +740,7 @@ mod print {
         }
     }
 
-    fn print_char(buf: &mut String, c: char, color: Option<StaticColor>) {
+    fn print_char(buf: &mut String, c: char, color: Option<ANSIStr<'static>>) {
         match color {
             Some(color) => {
                 buf.push_str(color.get_prefix());
@@ -754,8 +754,8 @@ mod print {
     fn print_line(
         buf: &mut String,
         border: Border<char>,
-        border_color: Border<StaticColor>,
-        color: Option<StaticColor>,
+        border_color: Border<ANSIStr<'static>>,
+        color: Option<ANSIStr<'static>>,
         c: char,
         width: usize,
     ) {
@@ -777,7 +777,7 @@ mod print {
     fn print_top_line(
         buf: &mut String,
         border: Border<char>,
-        color: Border<StaticColor>,
+        color: Border<ANSIStr<'static>>,
         splits: &[usize],
         split_char: char,
         width: usize,
@@ -786,7 +786,7 @@ mod print {
             return;
         }
 
-        let mut used_color: Option<StaticColor> = None;
+        let mut used_color: Option<ANSIStr<'static>> = None;
 
         if border.has_left() {
             if let Some(color) = color.left_top_corner {
@@ -858,14 +858,14 @@ mod print {
     fn print_bottom_line(
         buf: &mut String,
         border: Border<char>,
-        color: Border<StaticColor>,
+        color: Border<ANSIStr<'static>>,
         width: usize,
     ) {
         if !border.has_bottom() {
             return;
         }
 
-        let mut used_color: Option<StaticColor> = None;
+        let mut used_color: Option<ANSIStr<'static>> = None;
 
         if border.has_left() {
             if let Some(color) = color.left_bottom_corner {
@@ -986,7 +986,7 @@ mod print {
 
     struct ConfigCell(PrintContext);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for ConfigCell {
+    impl<R, D> TableOption<R, ColoredConfig, D> for ConfigCell {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             {
                 // we set a horizontal lines to borders to not complicate logic with cleaning it
@@ -1112,7 +1112,7 @@ mod print {
 
     struct NoTopBorders;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for NoTopBorders {
+    impl<R, D> TableOption<R, ColoredConfig, D> for NoTopBorders {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top = None;
@@ -1126,7 +1126,7 @@ mod print {
 
     struct NoBottomBorders;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for NoBottomBorders {
+    impl<R, D> TableOption<R, ColoredConfig, D> for NoBottomBorders {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom = None;
@@ -1140,7 +1140,7 @@ mod print {
 
     struct NoRightBorders;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for NoRightBorders {
+    impl<R, D> TableOption<R, ColoredConfig, D> for NoRightBorders {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_right = None;
@@ -1154,7 +1154,7 @@ mod print {
 
     struct NoLeftBorders;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for NoLeftBorders {
+    impl<R, D> TableOption<R, ColoredConfig, D> for NoLeftBorders {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = None;
@@ -1168,7 +1168,7 @@ mod print {
 
     struct TopLeftChangeTopIntersection;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeTopIntersection {
+    impl<R, D> TableOption<R, ColoredConfig, D> for TopLeftChangeTopIntersection {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = borders.top_intersection;
@@ -1179,7 +1179,7 @@ mod print {
 
     struct TopLeftChangeIntersection;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeIntersection {
+    impl<R, D> TableOption<R, ColoredConfig, D> for TopLeftChangeIntersection {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = borders.intersection;
@@ -1190,7 +1190,7 @@ mod print {
 
     struct TopLeftChangeToLeft;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for TopLeftChangeToLeft {
+    impl<R, D> TableOption<R, ColoredConfig, D> for TopLeftChangeToLeft {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_left = borders.left_intersection;
@@ -1201,7 +1201,7 @@ mod print {
 
     struct TopRightChangeToRight;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for TopRightChangeToRight {
+    impl<R, D> TableOption<R, ColoredConfig, D> for TopRightChangeToRight {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.top_right = borders.right_intersection;
@@ -1212,7 +1212,7 @@ mod print {
 
     struct BottomLeftChangeSplit;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplit {
+    impl<R, D> TableOption<R, ColoredConfig, D> for BottomLeftChangeSplit {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_left = borders.left_intersection;
@@ -1223,7 +1223,7 @@ mod print {
 
     struct BottomLeftChangeSplitToIntersection;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeSplitToIntersection {
+    impl<R, D> TableOption<R, ColoredConfig, D> for BottomLeftChangeSplitToIntersection {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_left = borders.intersection;
@@ -1234,7 +1234,7 @@ mod print {
 
     struct BottomRightChangeToRight;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for BottomRightChangeToRight {
+    impl<R, D> TableOption<R, ColoredConfig, D> for BottomRightChangeToRight {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_right = borders.right_intersection;
@@ -1245,7 +1245,7 @@ mod print {
 
     struct BottomLeftChangeToBottomIntersection;
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for BottomLeftChangeToBottomIntersection {
+    impl<R, D> TableOption<R, ColoredConfig, D> for BottomLeftChangeToBottomIntersection {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             let mut borders = *cfg.get_borders();
             borders.bottom_left = borders.bottom_intersection;
@@ -1256,7 +1256,7 @@ mod print {
 
     struct SetBottomChars<'a>(&'a [usize], char);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for SetBottomChars<'_>
+    impl<R, D> TableOption<R, ColoredConfig, D> for SetBottomChars<'_>
     where
         R: Records,
         for<'a> &'a R: Records,
@@ -1287,7 +1287,7 @@ mod print {
 
     struct SetTopChars<'a>(&'a [usize], char);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for SetTopChars<'_> {
+    impl<R, D> TableOption<R, ColoredConfig, D> for SetTopChars<'_> {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             for &split in self.0 {
                 let offset = split;
@@ -1298,7 +1298,7 @@ mod print {
 
     struct SetLeftChars<'a>(&'a [usize], char);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for SetLeftChars<'_> {
+    impl<R, D> TableOption<R, ColoredConfig, D> for SetLeftChars<'_> {
         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));
@@ -1308,7 +1308,7 @@ mod print {
 
     struct GetTopIntersection(char);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetTopIntersection {
+    impl<R, D> TableOption<R, ColoredConfig, D> for &mut GetTopIntersection {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             self.0 = cfg.get_borders().top_intersection.unwrap_or(' ');
         }
@@ -1316,7 +1316,7 @@ mod print {
 
     struct GetBottomIntersection(char);
 
-    impl<R, D> TableOption<R, D, ColoredConfig> for &mut GetBottomIntersection {
+    impl<R, D> TableOption<R, ColoredConfig, D> for &mut GetBottomIntersection {
         fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
             self.0 = cfg.get_borders().bottom_intersection.unwrap_or(' ');
         }
@@ -1562,7 +1562,11 @@ mod print {
         splits.iter_mut().enumerate().for_each(|(i, s)| *s += i);
     }
 
-    fn set_margin(table: &str, margin: Sides<Indent>, color: Sides<Option<StaticColor>>) -> String {
+    fn set_margin(
+        table: &str,
+        margin: Sides<Indent>,
+        color: Sides<Option<ANSIStr<'static>>>,
+    ) -> String {
         if table.is_empty() {
             return String::new();
         }
@@ -1599,7 +1603,9 @@ mod print {
         buf
     }
 
-    fn convert_border_colors(pad_color: Sides<StaticColor>) -> Sides<Option<StaticColor>> {
+    fn convert_border_colors(
+        pad_color: Sides<ANSIStr<'static>>,
+    ) -> Sides<Option<ANSIStr<'static>>> {
         Sides::new(
             (!pad_color.left.is_empty()).then(|| pad_color.left),
             (!pad_color.right.is_empty()).then(|| pad_color.right),
diff --git a/toml_to_table/Cargo.toml b/toml_to_table/Cargo.toml
index f46b6150..1774f51f 100644
--- a/toml_to_table/Cargo.toml
+++ b/toml_to_table/Cargo.toml
@@ -13,11 +13,14 @@ description = "A library for pretty print TOML as a table"
 license = "MIT"
 
 [features]
-color = ["tabled/color"]
+ansi = ["tabled/ansi"]
+derive = ["tabled/derive"]
+macros = ["tabled/macros"]
+
 
 [dependencies]
 toml = "0.7"
 tabled = { path = "../tabled", features = ["std"], default-features = false }
 
 [dev-dependencies]
-testing_table = { path = "../testing_table", features = ["color"] }
+testing_table = { path = "../testing_table", features = ["ansi"] }
diff --git a/toml_to_table/src/table/mod.rs b/toml_to_table/src/table/mod.rs
index aaba1435..587c985c 100644
--- a/toml_to_table/src/table/mod.rs
+++ b/toml_to_table/src/table/mod.rs
@@ -74,7 +74,7 @@ where
     /// Apply settings to the table.
     pub fn with<O>(&mut self, option: O) -> &mut Self
     where
-        O: TableOption<EmptyRecords, CompleteDimension<'static>, CompactMultilineConfig>,
+        O: TableOption<EmptyRecords, CompactMultilineConfig, CompleteDimension<'static>>,
     {
         let mut records = EmptyRecords::default();
         let mut dims = CompleteDimension::default();


Test patch:
diff --git a/json_to_table/tests/test_config.rs b/json_to_table/tests/test_config.rs
index f1f6cc0c..b935371a 100644
--- a/json_to_table/tests/test_config.rs
+++ b/json_to_table/tests/test_config.rs
@@ -4,8 +4,8 @@ use tabled::settings::{Alignment, Padding, Style};
 
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
-use tabled::{grid::color::AnsiColor, grid::config::ColoredConfig};
+#[cfg(feature = "ansi")]
+use tabled::{grid::ansi::ANSIBuf, grid::config::ColoredConfig};
 
 test_table!(
     config_from_table_test,
@@ -99,15 +99,15 @@ test_table!(
     "└─────┴──────┘"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     color_test,
     {
         struct ColorizeBorders;
 
-        impl<R, D> tabled::settings::TableOption<R, D, ColoredConfig> for ColorizeBorders {
+        impl<R, D> tabled::settings::TableOption<R, ColoredConfig, D> for ColorizeBorders {
             fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
-                cfg.set_border_color_global(AnsiColor::new("\u{1b}[34m".into(), "\u{1b}[39m".into()));
+                cfg.set_border_color_default(ANSIBuf::new("\u{1b}[34m", "\u{1b}[39m"));
             }
         }
 
diff --git a/papergrid/tests/grid/settings.rs b/papergrid/tests/grid/settings.rs
index 7e0446aa..fa9d0856 100644
--- a/papergrid/tests/grid/settings.rs
+++ b/papergrid/tests/grid/settings.rs
@@ -1,6 +1,6 @@
 #![cfg(feature = "std")]
 
-use papergrid::color::AnsiColor;
+use papergrid::ansi::ANSIBuf;
 use papergrid::config::{AlignmentHorizontal, Border, Borders, Entity, Indent, Sides};
 
 use crate::util::grid;
@@ -203,7 +203,7 @@ test_table!(
         .data([["Hello", "World"], ["", "Hello Hello Hello Hello Hello"]])
         .config(|cfg| {
             cfg.set_justification(Entity::Global, '$');
-            cfg.set_justification_color(Entity::Global, Some(AnsiColor::new("\u{1b}[34m".into(), "\u{1b}[39m".into())));
+            cfg.set_justification_color(Entity::Global, Some(ANSIBuf::new("\u{1b}[34m", "\u{1b}[39m")));
         })
         .build(),
         "+-----+-----------------------------+"
@@ -219,7 +219,7 @@ test_table!(
         .data([["Hello", "World"], ["", "Hello Hello Hello Hello Hello"]])
         .config(|cfg| {
             cfg.set_justification(Entity::Global, '$');
-            cfg.set_justification_color(Entity::Global, Some(AnsiColor::new("\u{1b}[34m".into(), "\u{1b}[39m".into())));
+            cfg.set_justification_color(Entity::Global, Some(ANSIBuf::new("\u{1b}[34m", "\u{1b}[39m")));
             cfg.set_alignment_horizontal(Entity::Global, AlignmentHorizontal::Right);
         })
         .build(),
@@ -236,7 +236,7 @@ test_table!(
         .data([["Hello", "World"], ["", "Hello Hello Hello Hello Hello"]])
         .config(|cfg| {
             cfg.set_justification(Entity::Global, '$');
-            cfg.set_justification_color(Entity::Global, Some(AnsiColor::new("\u{1b}[34m".into(), "\u{1b}[39m".into())));
+            cfg.set_justification_color(Entity::Global, Some(ANSIBuf::new("\u{1b}[34m", "\u{1b}[39m")));
             cfg.set_alignment_horizontal(Entity::Global, AlignmentHorizontal::Center);
         })
         .build(),
@@ -253,7 +253,7 @@ test_table!(
         .data([["Hello", "World"], ["", "Hello Hello Hello Hello Hello"]])
         .config(|cfg| {
             cfg.set_justification(Entity::Cell(0, 0), '$');
-            cfg.set_justification_color(Entity::Column(1), Some(AnsiColor::new("\u{1b}[34m".into(), "\u{1b}[39m".into())));
+            cfg.set_justification_color(Entity::Column(1), Some(ANSIBuf::new("\u{1b}[34m", "\u{1b}[39m")));
             cfg.set_alignment_horizontal(Entity::Row(2), AlignmentHorizontal::Center);
         })
         .build(),
diff --git a/papergrid/tests/grid/styling.rs b/papergrid/tests/grid/styling.rs
index b1886a8d..7e1ee8c8 100644
--- a/papergrid/tests/grid/styling.rs
+++ b/papergrid/tests/grid/styling.rs
@@ -5,8 +5,8 @@ use papergrid::config::{AlignmentHorizontal, Border, Borders, Entity, Indent, Si
 use crate::util::grid;
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
-use ::{owo_colors::OwoColorize, papergrid::color::AnsiColor, std::convert::TryFrom};
+#[cfg(feature = "ansi")]
+use ::{owo_colors::OwoColorize, papergrid::ansi::ANSIBuf, std::convert::TryFrom};
 
 test_table!(
     grid_2x2_custom_frame_test,
@@ -277,20 +277,20 @@ test_table!(
     "1-0*1-1"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     grid_2x2_ansi_border_test,
     grid(2, 2)
         .config(|cfg| {
             (0..2).for_each(|r| (0..2).for_each(|c| {
-                let top = AnsiColor::try_from(" ".green().on_red().to_string()).unwrap();
-                let bottom = AnsiColor::try_from(" ".on_green().blue().to_string()).unwrap();
-                let left = AnsiColor::try_from(" ".on_red().white().to_string()).unwrap();
-                let right = AnsiColor::try_from(" ".on_red().green().to_string()).unwrap();
-                let tl = AnsiColor::try_from(" ".magenta().to_string()).unwrap();
-                let tr = AnsiColor::try_from(" ".on_blue().to_string()).unwrap();
-                let bl = AnsiColor::try_from(" ".yellow().to_string()).unwrap();
-                let br = AnsiColor::try_from(" ".on_yellow().to_string()).unwrap();
+                let top = ANSIBuf::try_from(" ".green().on_red().to_string()).unwrap();
+                let bottom = ANSIBuf::try_from(" ".on_green().blue().to_string()).unwrap();
+                let left = ANSIBuf::try_from(" ".on_red().white().to_string()).unwrap();
+                let right = ANSIBuf::try_from(" ".on_red().green().to_string()).unwrap();
+                let tl = ANSIBuf::try_from(" ".magenta().to_string()).unwrap();
+                let tr = ANSIBuf::try_from(" ".on_blue().to_string()).unwrap();
+                let bl = ANSIBuf::try_from(" ".yellow().to_string()).unwrap();
+                let br = ANSIBuf::try_from(" ".on_yellow().to_string()).unwrap();
 
                 cfg.set_border((r, c), Border::full('*', '#', '~', '!', '@', '$', '%', '^'));
                 cfg.set_border_color((r, c), Border::full(top, bottom, left, right, tl, tr, bl, br));
@@ -304,13 +304,13 @@ test_table!(
     "\u{1b}[33m%\u{1b}[39m\u{1b}[34m\u{1b}[42m###\u{1b}[39m\u{1b}[49m\u{1b}[33m%\u{1b}[39m\u{1b}[34m\u{1b}[42m###\u{1b}[39m\u{1b}[49m\u{1b}[43m^\u{1b}[49m"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     grid_2x2_ansi_global_set_test,
     grid(2, 2)
         .config(|cfg| {
             let color = " ".on_blue().red().bold().to_string();
-            cfg.set_border_color_global(AnsiColor::try_from(color).unwrap());
+            cfg.set_border_color_default(ANSIBuf::try_from(color).unwrap());
         })
         .build(),
     "\u{1b}[1m\u{1b}[31m\u{1b}[44m+---+---+\u{1b}[22m\u{1b}[39m\u{1b}[49m"
@@ -320,15 +320,15 @@ test_table!(
     "\u{1b}[1m\u{1b}[31m\u{1b}[44m+---+---+\u{1b}[22m\u{1b}[39m\u{1b}[49m"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn grid_2x2_ansi_border_none_if_string_is_not_1_char_test() {
-    assert!(AnsiColor::try_from("12").is_ok());
-    assert!(AnsiColor::try_from("123").is_ok());
-    assert!(AnsiColor::try_from("").is_err());
+    assert!(ANSIBuf::try_from("12").is_ok());
+    assert!(ANSIBuf::try_from("123").is_ok());
+    assert!(ANSIBuf::try_from("").is_err());
 
-    assert!(AnsiColor::try_from("1").is_ok());
-    assert!(AnsiColor::try_from("1".on_red().to_string()).is_ok());
-    assert!(AnsiColor::try_from("1".on_red().blue().to_string()).is_ok());
-    assert!(AnsiColor::try_from("1".truecolor(0, 1, 3).on_truecolor(1, 2, 3).to_string()).is_ok());
+    assert!(ANSIBuf::try_from("1").is_ok());
+    assert!(ANSIBuf::try_from("1".on_red().to_string()).is_ok());
+    assert!(ANSIBuf::try_from("1".on_red().blue().to_string()).is_ok());
+    assert!(ANSIBuf::try_from("1".truecolor(0, 1, 3).on_truecolor(1, 2, 3).to_string()).is_ok());
 }
diff --git a/tabled/tests/core/extended_table_test.rs b/tabled/tests/core/extended_table_test.rs
index 8e511127..0a07f6b0 100644
--- a/tabled/tests/core/extended_table_test.rs
+++ b/tabled/tests/core/extended_table_test.rs
@@ -1,6 +1,6 @@
 #![cfg(feature = "std")]
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use owo_colors::{AnsiColors, OwoColorize};
 
 use tabled::{tables::ExtendedTable, Tabled};
@@ -403,7 +403,7 @@ test_table!(
     "column 2 | 2-2"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn display_colored() {
     let mut data = Matrix::list::<3, 3>();
@@ -439,7 +439,7 @@ fn display_colored() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn display_with_truncate_colored() {
     let mut data = Matrix::list::<2, 3>();
diff --git a/tabled/tests/core/pool_table.rs b/tabled/tests/core/pool_table.rs
index ee28dae7..01a145f0 100644
--- a/tabled/tests/core/pool_table.rs
+++ b/tabled/tests/core/pool_table.rs
@@ -9,8 +9,8 @@ use tabled::{
 use crate::matrix::Matrix;
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
-use tabled::grid::color::StaticColor;
+#[cfg(feature = "ansi")]
+use tabled::grid::ansi::ANSIStr;
 
 test_table!(
     pool_table,
@@ -309,17 +309,17 @@ test_table!(
     "+------+------+------+"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     pool_table_padding_2,
     PoolTable::new(Matrix::with_no_frame(3, 3).to_vec())
         .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"),
+                ANSIStr::new("\u{1b}[34m", "\u{1b}[39m"),
+                ANSIStr::new("\u{1b}[34m", "\u{1b}[39m"),
+                ANSIStr::new("\u{1b}[34m", "\u{1b}[39m"),
+                ANSIStr::new("\u{1b}[34m", "\u{1b}[39m"),
             )
         ),
     "+------+------+------+"
diff --git a/tabled/tests/core/table_test.rs b/tabled/tests/core/table_test.rs
index 793986af..a3ac80ba 100644
--- a/tabled/tests/core/table_test.rs
+++ b/tabled/tests/core/table_test.rs
@@ -749,7 +749,7 @@ mod derived {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn multiline_table_test2() {
     use testing_table::assert_table;
diff --git a/tabled/tests/matrix/matrix.rs b/tabled/tests/matrix/matrix.rs
index 3a55a7a8..dcc73703 100644
--- a/tabled/tests/matrix/matrix.rs
+++ b/tabled/tests/matrix/matrix.rs
@@ -95,8 +95,8 @@ impl Matrix {
     where
         for<'a> O: TableOption<
             VecRecords<CellInfo<String>>,
-            CompleteDimensionVecRecords<'a>,
             ColoredConfig,
+            CompleteDimensionVecRecords<'a>,
         >,
     {
         let mut table = self.to_table();
diff --git a/tabled/tests/settings/format_test.rs b/tabled/tests/settings/format_test.rs
index 82585ca6..9d35ffc0 100644
--- a/tabled/tests/settings/format_test.rs
+++ b/tabled/tests/settings/format_test.rs
@@ -8,7 +8,7 @@ use tabled::settings::{
 use crate::matrix::Matrix;
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use owo_colors::OwoColorize;
 
 test_table!(
@@ -227,7 +227,7 @@ test_table!(
     "+-------------+-------------+-------------+-------------+"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     color_test,
     Matrix::new(3, 3)
@@ -244,7 +244,7 @@ test_table!(
     " \u{1b}[31m2\u{1b}[39m |   \u{1b}[34m2-0\u{1b}[39m    |   \u{1b}[31m2-1\u{1b}[39m    |   \u{1b}[31m2-2\u{1b}[39m    "
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     color_multiline_test,
     Matrix::new(3, 3)
diff --git a/tabled/tests/settings/height_test.rs b/tabled/tests/settings/height_test.rs
index 48d6a636..428b6918 100644
--- a/tabled/tests/settings/height_test.rs
+++ b/tabled/tests/settings/height_test.rs
@@ -8,7 +8,7 @@ use tabled::settings::{
 use crate::matrix::Matrix;
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use owo_colors::OwoColorize;
 
 test_table!(
@@ -198,7 +198,7 @@ test_table!(
         "|      |      |      |      |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     cell_height_limit_colored,
     Matrix::new(3, 3)
@@ -218,7 +218,7 @@ test_table!(
         "| \u{1b}[31mxxxx\u{1b}[39m |   2-0    |   2-1    |   2-2    |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     table_height_limit_colored,
     Matrix::new(3, 3)
diff --git a/tabled/tests/settings/margin_test.rs b/tabled/tests/settings/margin_test.rs
index 8a7c14f2..6da45185 100644
--- a/tabled/tests/settings/margin_test.rs
+++ b/tabled/tests/settings/margin_test.rs
@@ -5,7 +5,7 @@ use tabled::settings::{object::Cell, Border, Highlight, Margin, Modify, Span, St
 use crate::matrix::Matrix;
 use testing_table::{is_lines_equal, static_table, test_table};
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use ::{owo_colors::OwoColorize, std::convert::TryFrom, tabled::settings::Color};
 
 test_table!(
@@ -165,7 +165,7 @@ fn margin_color_test_not_colored_feature() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn margin_color_test() {
     let table = Matrix::new(3, 3)
diff --git a/tabled/tests/settings/padding_test.rs b/tabled/tests/settings/padding_test.rs
index 9a3edb4a..7777769e 100644
--- a/tabled/tests/settings/padding_test.rs
+++ b/tabled/tests/settings/padding_test.rs
@@ -8,7 +8,7 @@ use tabled::settings::{
 use crate::matrix::Matrix;
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use ::{owo_colors::OwoColorize, std::convert::TryFrom, tabled::settings::Color};
 
 test_table!(
@@ -99,7 +99,7 @@ test_table!(
     "   |          |          |          "
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     padding_color,
     {
diff --git a/tabled/tests/settings/render_settings.rs b/tabled/tests/settings/render_settings.rs
index f25a59a6..02e506ce 100644
--- a/tabled/tests/settings/render_settings.rs
+++ b/tabled/tests/settings/render_settings.rs
@@ -9,7 +9,7 @@ use tabled::settings::{
 use crate::matrix::{Matrix, MatrixList};
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use owo_colors::OwoColorize;
 
 test_table!(
@@ -181,7 +181,7 @@ test_table!(
     "└─────────────────┘"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     trim_colored_string_test_2,
     Matrix::iter(colored_data())
@@ -204,7 +204,7 @@ test_table!(
     "           |          | \u{1b}[44m/en\u{1b}[49m      |          "
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     trim_colored_string_test_1,
     Matrix::iter(colored_data())
@@ -231,7 +231,7 @@ test_table!(
     "           |          |     \u{1b}[44m.com\u{1b}[49m |          "
     "           |          |      \u{1b}[44m/en\u{1b}[49m |          "
 );
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     trim_colored_string_test_0,
     Matrix::iter(colored_data())
@@ -283,7 +283,7 @@ fn tab_data2() -> Vec<MatrixList<3, true>> {
     data
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 fn colored_data() -> Vec<MatrixList<3, true>> {
     let mut data = Matrix::list::<3, 3>();
     data[1][0] = "asd\n21213123\n\n   asdasd\n\n".red().to_string();
diff --git a/tabled/tests/settings/shadow_test.rs b/tabled/tests/settings/shadow_test.rs
index 2d169698..7cd0d2b5 100644
--- a/tabled/tests/settings/shadow_test.rs
+++ b/tabled/tests/settings/shadow_test.rs
@@ -5,7 +5,7 @@ use tabled::settings::{Shadow, Style};
 use crate::matrix::Matrix;
 use testing_table::test_table;
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use ::{owo_colors::OwoColorize, std::convert::TryFrom, tabled::settings::Color};
 
 test_table!(
@@ -89,7 +89,7 @@ test_table!(
     "   ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     test_shadow_set_color_0,
     Matrix::iter([(123, 456, 789), (234, 567, 891)]).with(Shadow::new(2).set_offset(3).set_color(Color::try_from(' '.red().to_string()).unwrap())),
diff --git a/tabled/tests/settings/style_test.rs b/tabled/tests/settings/style_test.rs
index 29455973..949a8523 100644
--- a/tabled/tests/settings/style_test.rs
+++ b/tabled/tests/settings/style_test.rs
@@ -20,7 +20,7 @@ use tabled::{
 use crate::matrix::Matrix;
 use testing_table::{static_table, test_table};
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use ::{owo_colors::OwoColorize, std::convert::TryFrom};
 
 test_table!(
@@ -347,7 +347,7 @@ test_table!(
     "+\u{1b}[31m---\u{1b}[39m+\u{1b}[31m----------\u{1b}[39m+\u{1b}[31m----------\u{1b}[39m+"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     border_text_colored,
     Matrix::table(2, 2)
@@ -2067,7 +2067,7 @@ fn test_default_border_usage() {
     }
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn border_colored_test() {
     let table = Matrix::table(2, 2)
@@ -2137,7 +2137,7 @@ fn border_colored_test() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn style_with_color_test() {
     let mut style = Theme::from_style(Style::ascii());
diff --git a/tabled/tests/settings/width_test.rs b/tabled/tests/settings/width_test.rs
index 38db7353..f52a3798 100644
--- a/tabled/tests/settings/width_test.rs
+++ b/tabled/tests/settings/width_test.rs
@@ -14,10 +14,10 @@ use tabled::{
 use crate::matrix::Matrix;
 use testing_table::{is_lines_equal, static_table, test_table};
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 use ::{ansi_str::AnsiStr, owo_colors::OwoColorize, tabled::settings::style::HorizontalLine};
 
-#[cfg(all(feature = "derive", feature = "color"))]
+#[cfg(all(feature = "derive", feature = "ansi"))]
 use ::owo_colors::AnsiColors;
 
 test_table!(
@@ -143,7 +143,7 @@ test_table!(
     "| sentence          |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_3,
     {
@@ -164,7 +164,7 @@ test_table!(
     "|  sentence         |"
 );
 
-#[cfg(not(feature = "color"))]
+#[cfg(not(feature = "ansi"))]
 test_table!(
     max_width_wrapped_keep_words_3,
     {
@@ -202,7 +202,7 @@ test_table!(
     "| this |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_0,
     {
@@ -220,7 +220,7 @@ test_table!(
     "| sentence          |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_0_1,
     Matrix::iter(vec!["this is a long sentence".on_black().green().to_string()])
@@ -233,7 +233,7 @@ test_table!(
         "| \u{1b}[32m\u{1b}[40msentence\u{1b}[39m\u{1b}[49m          |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_1,
     {
@@ -251,7 +251,7 @@ test_table!(
     "| sentence          |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_1_1,
     Matrix::iter(vec!["this is a long  sentence".on_black().green().to_string()])
@@ -264,7 +264,7 @@ test_table!(
     "| \u{1b}[32m\u{1b}[40msentence\u{1b}[39m\u{1b}[49m          |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_2,
     {
@@ -282,7 +282,7 @@ test_table!(
     "| sentence          |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_2_1,
     Matrix::iter(vec!["this is a long   sentence".on_black().green().to_string()])
@@ -295,7 +295,7 @@ test_table!(
     "| \u{1b}[32m\u{1b}[40msentence\u{1b}[39m\u{1b}[49m          |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_3,
     {
@@ -313,7 +313,7 @@ test_table!(
     "|  sentence         |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_3_1,
     Matrix::iter(vec!["this is a long    sentence".on_black().green().to_string()])
@@ -326,7 +326,7 @@ test_table!(
     "| \u{1b}[32m\u{1b}[40m sentence\u{1b}[39m\u{1b}[49m         |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_4,
     {
@@ -342,7 +342,7 @@ test_table!(
     "|  this  |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 test_table!(
     max_width_wrapped_keep_words_color_4_1,
     Matrix::iter(vec!["this".on_black().green().to_string()])
@@ -366,7 +366,7 @@ test_table!(
     "| tence             |"
 );
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn max_width_wrapped_keep_words_long_word_color() {
     let data = vec!["this is a long sentencesentencesentence"
@@ -402,7 +402,7 @@ fn max_width_wrapped_keep_words_long_word_color() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn max_width_keep_words_1() {
     let table = Matrix::iter(["asdf"])
@@ -469,7 +469,7 @@ fn max_width_keep_words_1() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn max_width_wrapped_collored() {
     let data = &[
@@ -529,7 +529,7 @@ fn max_width_with_emoji() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn color_chars_are_stripped() {
     let data = &[
@@ -795,7 +795,7 @@ fn min_with_max_width_truncate_suffix_limit_ignore() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn min_with_max_width_truncate_suffix_try_color() {
     let data = &[
@@ -821,7 +821,7 @@ fn min_with_max_width_truncate_suffix_try_color() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn min_width_color() {
     let data = &[
@@ -852,7 +852,7 @@ fn min_width_color() {
     );
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn min_width_color_with_smaller_then_width() {
     let data = &[
@@ -1140,7 +1140,7 @@ fn total_width_small_with_panel() {
     assert!(is_lines_equal(&table, 14));
 }
 
-#[cfg(feature = "color")]
+#[cfg(feature = "ansi")]
 #[test]
 fn total_width_wrapping() {
     let table = Matrix::new(3, 3)
@@ -2510,7 +2510,7 @@ mod derived {
         assert!(is_lines_equal(&table, 57));
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn wrapping_as_total_multiline_color() {
         #[derive(Tabled)]
@@ -2595,7 +2595,7 @@ mod derived {
         assert_eq!(string_width_multiline(&table), 57);
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn truncating_as_total_multiline_color() {
         #[derive(Tabled)]
@@ -2657,7 +2657,7 @@ mod derived {
         assert_eq!(string_width_multiline(&table), 57);
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     fn format_osc8_hyperlink(url: &str, text: &str) -> String {
         format!(
             "{osc}8;;{url}{st}{text}{osc}8;;{st}",
@@ -2668,7 +2668,7 @@ mod derived {
         )
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn hyperlinks() {
         #[derive(Tabled)]
@@ -2748,7 +2748,7 @@ mod derived {
         );
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     #[test]
     fn hyperlinks_with_color() {
         use owo_colors::OwoColorize;
diff --git a/testing_table/Cargo.toml b/testing_table/Cargo.toml
index 2a8a1492..66716490 100644
--- a/testing_table/Cargo.toml
+++ b/testing_table/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2018"
 publish = false
 
 [features]
-color = ["ansitok"]
+ansi = ["ansitok"]
 
 [dependencies]
 ansitok = { version = "0.2", optional = true }
diff --git a/testing_table/src/lib.rs b/testing_table/src/lib.rs
index 95e99606..f13f5d8d 100644
--- a/testing_table/src/lib.rs
+++ b/testing_table/src/lib.rs
@@ -5,7 +5,7 @@ pub fn is_lines_equal(s: &str, width: usize) -> bool {
 }
 
 fn string_width_multiline(text: &str) -> usize {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         text.lines()
             .map(unicode_width::UnicodeWidthStr::width)
@@ -13,7 +13,7 @@ fn string_width_multiline(text: &str) -> usize {
             .unwrap_or(0)
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         text.lines().map(string_width).max().unwrap_or(0)
     }
@@ -21,12 +21,12 @@ fn string_width_multiline(text: &str) -> usize {
 
 #[allow(dead_code)]
 fn string_width(text: &str) -> usize {
-    #[cfg(not(feature = "color"))]
+    #[cfg(not(feature = "ansi"))]
     {
         unicode_width::UnicodeWidthStr::width(text)
     }
 
-    #[cfg(feature = "color")]
+    #[cfg(feature = "ansi")]
     {
         // we need to strip ansi because of terminal links
         // and they're can't be stripped by ansi_str.