Repository: zhiburt/tabled
Pull request #512 (2025-03-17 22:36:32)

Add a `#[tabled(map = "map_function")]`


Patch:
diff --git a/tabled/Cargo.toml b/tabled/Cargo.toml
index 148b99d..0ff63da 100644
--- a/tabled/Cargo.toml
+++ b/tabled/Cargo.toml
@@ -88,6 +88,16 @@ name = "derive_format_enum"
 path = "examples/derive/format_enum.rs"
 required-features = ["derive"]
 
+[[example]]
+name = "derive_map"
+path = "examples/derive/map.rs"
+required-features = ["derive"]
+
+[[example]]
+name = "derive_map_inlined"
+path = "examples/derive/map_inlined.rs"
+required-features = ["derive"]
+
 [[example]]
 name = "table"
 path = "examples/table.rs"
diff --git a/tabled/examples/derive/map.rs b/tabled/examples/derive/map.rs
new file mode 100644
index 0000000..47eb9ca
--- /dev/null
+++ b/tabled/examples/derive/map.rs
@@ -0,0 +1,39 @@
+use tabled::{Table, Tabled};
+
+#[derive(Tabled)]
+struct Vehicle {
+    vtype: String,
+    #[tabled(map = "String::from")]
+    engine_type: EngineType,
+}
+
+enum EngineType {
+    V8,
+    V12,
+}
+
+impl From<&EngineType> for String {
+    fn from(value: &EngineType) -> Self {
+        match value {
+            EngineType::V8 => "V8".to_string(),
+            EngineType::V12 => "V12".to_string(),
+        }
+    }
+}
+
+fn main() {
+    let data = [
+        Vehicle {
+            vtype: String::from("limousine"),
+            engine_type: EngineType::V8,
+        },
+        Vehicle {
+            vtype: String::from("sport"),
+            engine_type: EngineType::V12,
+        },
+    ];
+
+    let table = Table::new(data);
+
+    println!("{table}");
+}
diff --git a/tabled/examples/derive/map_inlined.rs b/tabled/examples/derive/map_inlined.rs
new file mode 100644
index 0000000..a1d960b
--- /dev/null
+++ b/tabled/examples/derive/map_inlined.rs
@@ -0,0 +1,48 @@
+use tabled::{Table, Tabled};
+
+#[derive(Tabled)]
+struct Vehicle {
+    vtype: String,
+    #[tabled(inline("engine->"), map(Engine, "Self::parse_engine"))]
+    engine: String,
+}
+
+#[derive(Tabled)]
+struct Engine {
+    cylinder_amount: u8,
+    oil_change_cycle: u8,
+    disel: bool,
+}
+
+impl Vehicle {
+    fn new(vtype: &str, engine: &str) -> Self {
+        Self {
+            vtype: vtype.to_string(),
+            engine: engine.to_string(),
+        }
+    }
+
+    fn parse_engine(text: &str) -> Engine {
+        let mut settings = text.split(";");
+        let cylinder_amount = settings.next().unwrap().parse().unwrap();
+        let oil_change_cycle = settings.next().unwrap().parse().unwrap();
+        let disel = settings.next().unwrap().parse().unwrap();
+
+        Engine {
+            cylinder_amount,
+            oil_change_cycle,
+            disel,
+        }
+    }
+}
+
+fn main() {
+    let data = [
+        Vehicle::new("limousine", "3;12;false"),
+        Vehicle::new("sport", "12;4;true"),
+    ];
+
+    let table = Table::new(data);
+
+    println!("{table}");
+}
diff --git a/tabled_derive/src/attributes/field_attr.rs b/tabled_derive/src/attributes/field_attr.rs
index 1eedf77..1276da6 100644
--- a/tabled_derive/src/attributes/field_attr.rs
+++ b/tabled_derive/src/attributes/field_attr.rs
@@ -1,4 +1,4 @@
-use syn::{Attribute, LitInt};
+use syn::{Attribute, LitInt, Type};
 
 use crate::{
     casing_style::CasingStyle,
@@ -15,9 +15,11 @@ pub struct FieldAttributes {
     pub rename_all: Option<CasingStyle>,
     pub display_with: Option<String>,
     pub display_with_args: Option<Vec<FormatArg>>,
-    pub order: Option<usize>,
     pub format: Option<String>,
     pub format_with_args: Option<Vec<FormatArg>>,
+    pub map: Option<String>,
+    pub map_type: Option<Type>,
+    pub order: Option<usize>,
 }
 
 pub struct FormatArg {
@@ -83,6 +85,12 @@ impl FieldAttributes {
                     self.format_with_args = Some(args);
                 }
             }
+            FieldAttrKind::Map(func, ret_type) => {
+                self.map = Some(func.value());
+                if let Some((_, ret_type)) = ret_type {
+                    self.map_type = Some(ret_type);
+                }
+            }
             FieldAttrKind::Order(value) => self.order = Some(lit_int_to_usize(&value)?),
         }
 
diff --git a/tabled_derive/src/lib.rs b/tabled_derive/src/lib.rs
index 1977334..cec749d 100644
--- a/tabled_derive/src/lib.rs
+++ b/tabled_derive/src/lib.rs
@@ -15,6 +15,7 @@ use proc_macro2::TokenStream;
 use proc_macro_error2::proc_macro_error;
 use quote::{quote, ToTokens, TokenStreamExt};
 use std::{collections::HashMap, str};
+use syn::spanned::Spanned;
 use syn::visit_mut::VisitMut;
 use syn::{
     parse_macro_input, token, Data, DataEnum, DataStruct, DeriveInput, ExprPath, Field, Fields,
@@ -100,12 +101,25 @@ fn get_fields_length(fields: &Fields, tabled_trait: &ExprPath) -> Result<TokenSt
         .filter(|(_, attr)| !attr.is_ignored)
         .map(|(field, attr)| {
             if attr.inline {
-                let field_type = &field.ty;
-                quote!({<#field_type as #tabled_trait>::LENGTH})
+                if attr.map.is_some() {
+                    match attr.map_type {
+                        Some(map_type) => Ok(quote!({ <#map_type as #tabled_trait>::LENGTH })),
+                        None => Err(Error::new(
+                            "map type was not given",
+                            field.span(),
+                            Some(String::from("provide a type to map attribute")),
+                        )),
+                    }
+                } else {
+                    let field_type = &field.ty;
+                    Ok(quote!({<#field_type as #tabled_trait>::LENGTH}))
+                }
             } else {
-                quote!({ 1 })
+                Ok(quote!({ 1 }))
             }
-        });
+        })
+        .collect::<Result<Vec<_>, Error>>()?
+        .into_iter();
 
     let size_components = std::iter::once(quote!(0)).chain(size_components);
 
@@ -285,19 +299,29 @@ fn reorder_fields<T: Clone>(order: &HashMap<usize, usize>, elements: &[T]) -> Ve
 fn field_headers(
     field: &Field,
     index: usize,
-    attributes: &FieldAttributes,
+    attrs: &FieldAttributes,
     prefix: &str,
     trait_path: &ExprPath,
 ) -> TokenStream {
-    if attributes.inline {
-        let prefix = attributes
+    if attrs.inline {
+        let prefix = attrs
             .inline_prefix
             .as_ref()
             .map_or_else(|| "", |s| s.as_str());
+
+        if attrs.map.is_some() {
+            if let Some(map_type) = &attrs.map_type {
+                return get_type_headers(map_type, prefix, "", trait_path);
+            } else {
+                // NOTE: A panic already must have been raised
+                unreachable!();
+            }
+        }
+
         return get_type_headers(&field.ty, prefix, "", trait_path);
     }
 
-    let header_name = field_header_name(field, attributes, index);
+    let header_name = field_header_name(field, attrs, index);
     if prefix.is_empty() {
         quote!(vec![::std::borrow::Cow::Borrowed(#header_name)])
     } else {
@@ -484,13 +508,34 @@ fn get_field_fields(
     field_name: FieldNameFn,
     type_attrs: &TypeAttributes,
 ) -> TokenStream {
+    let mut field = std::borrow::Cow::Borrowed(field);
+    if let Some(map_fn) = &attr.map {
+        let arg = quote!(&#field);
+        let result = use_function(&arg, map_fn);
+        field = std::borrow::Cow::Owned(result);
+
+        if attr.inline {
+            return quote! {
+                {
+                    let field = #field;
+                    let fields = field.fields();
+                    let fields = fields.into_iter()
+                        .map(|f| f.into_owned())
+                        .map(std::borrow::Cow::Owned)
+                        .collect::<Vec<_>>();
+                    fields
+                }
+            };
+        }
+    }
+
     if attr.inline {
         return quote! { #field.fields() };
     }
 
     if let Some(func) = &attr.display_with {
         let args = match &attr.display_with_args {
-            Some(args) => args_to_tokens_with(fields, field, field_name, args),
+            Some(args) => args_to_tokens_with(fields, &field, field_name, args),
             None => quote!(&#field),
         };
 
@@ -505,7 +550,7 @@ fn get_field_fields(
 
         let call = match args {
             Some(args) => use_format(fmt, &args),
-            None => use_format_with_one_arg(fmt, field),
+            None => use_format_with_one_arg(fmt, &field),
         };
 
         return quote!(vec![::std::borrow::Cow::Owned(#call)]);
@@ -513,7 +558,7 @@ fn get_field_fields(
 
     if let Some(i) = find_display_type(field_type, &type_attrs.display_types) {
         let (_, func, args) = &type_attrs.display_types[i];
-        let args = args_to_tokens_with(fields, field, field_name, args);
+        let args = args_to_tokens_with(fields, &field, field_name, args);
         let func = use_function(&args, func);
 
         return quote!(vec![::std::borrow::Cow::from(#func)]);
diff --git a/tabled_derive/src/parse/field_attr.rs b/tabled_derive/src/parse/field_attr.rs
index f21d534..8c0add9 100644
--- a/tabled_derive/src/parse/field_attr.rs
+++ b/tabled_derive/src/parse/field_attr.rs
@@ -1,7 +1,7 @@
 use proc_macro2::{Ident, Span};
 use syn::{
     parenthesized, parse::Parse, punctuated::Punctuated, spanned::Spanned, token, Attribute,
-    LitBool, LitInt, LitStr, Token,
+    LitBool, LitInt, LitStr, Token, Type,
 };
 
 pub fn parse_field_attributes(
@@ -31,8 +31,9 @@ pub enum FieldAttrKind {
     Rename(LitStr),
     RenameAll(LitStr),
     DisplayWith(LitStr, Option<Token!(,)>, Punctuated<syn::Expr, Token!(,)>),
-    Order(LitInt),
     FormatWith(LitStr, Option<Token!(,)>, Punctuated<syn::Expr, Token!(,)>),
+    Map(LitStr, Option<(Token!(,), Type)>),
+    Order(LitInt),
 }
 
 impl Parse for FieldAttr {
@@ -53,6 +54,7 @@ impl Parse for FieldAttr {
                     "rename_all" => return Ok(Self::new(RenameAll(lit))),
                     "display" => return Ok(Self::new(DisplayWith(lit, None, Punctuated::new()))),
                     "format" => return Ok(Self::new(FormatWith(lit, None, Punctuated::new()))),
+                    "map" => return Ok(Self::new(Map(lit, None))),
                     _ => {}
                 }
             }
@@ -85,40 +87,54 @@ impl Parse for FieldAttr {
             let nested;
             let _paren = parenthesized!(nested in input);
 
-            if nested.peek(LitStr) {
-                let lit = nested.parse::<LitStr>()?;
-
-                match name_str.as_str() {
-                    "format" | "display" => {
-                        let mut args = Punctuated::new();
-                        let mut comma = None;
-                        if nested.peek(Token![,]) {
-                            comma = Some(nested.parse::<Token![,]>()?);
-                            while !nested.is_empty() {
-                                let val = nested.parse()?;
-                                args.push_value(val);
-                                if nested.is_empty() {
-                                    break;
-                                }
-                                let punct = nested.parse()?;
-                                args.push_punct(punct);
+            match name_str.as_str() {
+                "map" => {
+                    let path = nested.parse::<Type>().map_err(|_| {
+                        syn::Error::new(
+                            _paren.span.span(),
+                            "expected to get a return type of map function",
+                        )
+                    })?;
+                    let comma = nested.parse::<Token![,]>().map_err(|_| {
+                        syn::Error::new(_paren.span.span(), "expected to get a comma")
+                    })?;
+                    let lit = nested.parse::<LitStr>()?;
+
+                    return Ok(Self::new(Map(lit, Some((comma, path)))));
+                }
+                "format" | "display" => {
+                    let lit = nested.parse::<LitStr>()?;
+
+                    let mut args = Punctuated::new();
+                    let mut comma = None;
+                    if nested.peek(Token![,]) {
+                        comma = Some(nested.parse::<Token![,]>()?);
+                        while !nested.is_empty() {
+                            let val = nested.parse()?;
+                            args.push_value(val);
+                            if nested.is_empty() {
+                                break;
                             }
-                        };
-
-                        if name_str.as_str() == "format" {
-                            return Ok(Self::new(FormatWith(lit, comma, args)));
+                            let punct = nested.parse()?;
+                            args.push_punct(punct);
                         }
+                    };
 
-                        return Ok(Self::new(DisplayWith(lit, comma, args)));
+                    if name_str.as_str() == "format" {
+                        return Ok(Self::new(FormatWith(lit, comma, args)));
                     }
-                    "inline" => {
-                        return Ok(Self::new(Inline(
-                            LitBool::new(true, Span::call_site()),
-                            Some(lit),
-                        )))
-                    }
-                    _ => {}
+
+                    return Ok(Self::new(DisplayWith(lit, comma, args)));
+                }
+                "inline" => {
+                    let lit = nested.parse::<LitStr>()?;
+
+                    return Ok(Self::new(Inline(
+                        LitBool::new(true, Span::call_site()),
+                        Some(lit),
+                    )));
                 }
+                _ => {}
             }
 
             return Err(syn::Error::new(
diff --git a/tabled_derive/src/parse/type_attr.rs b/tabled_derive/src/parse/type_attr.rs
index 1004b5e..43c3662 100644
--- a/tabled_derive/src/parse/type_attr.rs
+++ b/tabled_derive/src/parse/type_attr.rs
@@ -76,15 +76,12 @@ impl Parse for TypeAttr {
             let nested;
             let _paren = parenthesized!(nested in input);
 
-            if nested.peek(LitStr) {
+            if name_str.as_str() == "inline" && nested.peek(LitStr) {
                 let lit = nested.parse::<LitStr>()?;
-
-                if name_str.as_str() == "inline" {
-                    return Ok(Self::new(Inline(
-                        LitBool::new(true, Span::call_site()),
-                        Some(lit),
-                    )));
-                }
+                return Ok(Self::new(Inline(
+                    LitBool::new(true, Span::call_site()),
+                    Some(lit),
+                )));
             }
 
             if name_str.as_str() == "display" {


Test patch:
diff --git a/tabled/tests/derive/derive_test.rs b/tabled/tests/derive/derive_test.rs
index f5bfa57..aa610a9 100644
--- a/tabled/tests/derive/derive_test.rs
+++ b/tabled/tests/derive/derive_test.rs
@@ -1,1378 +1,103 @@
 #![cfg(feature = "derive")]
-#![cfg(feature = "std")]
 
-use std::fmt::Display;
+use tabled::Tabled;
 
-use tabled::{Table, Tabled};
-use testing_table::test_table;
+use super::{sstr, test_enum, test_struct, test_tuple};
 
-// https://users.rust-lang.org/t/create-a-struct-from-macro-rules/19829
-macro_rules! test_tuple {
-    (
-        $test_name:ident,
-        { $(#[$struct_attr:meta])* { $( $(#[$attr:meta])* $ty:ty)* } },
-        { $($init:expr)* },
-        { $headers:expr, $fields:expr } $(,)?
-        $(pre: { $($init_block:stmt)* })?
-    ) => {
-        #[test]
-        fn $test_name() {
-            $($($init_block)*)?
-
-            #[derive(Tabled)]
-            $(#[$struct_attr])*
-            #[allow(dead_code)]
-            struct TestType(
-                $( $(#[$attr])* $ty, )*
-            );
-
-            let value = TestType($($init,)*);
-
-            let fields: Vec<&'static str> = $fields.to_vec();
-            let headers: Vec<&'static str> = $headers.to_vec();
-
-            assert_eq!(value.fields(), fields);
-            assert_eq!(TestType::headers(), headers);
-            assert_eq!(<TestType as Tabled>::LENGTH, headers.len());
-            assert_eq!(<TestType as Tabled>::LENGTH, fields.len());
-        }
-    };
-}
-
-macro_rules! test_enum {
-    (
-        $test_name:ident,
-        { $(#[$struct_attr:meta])* { $( $(#[$var_attr:meta])*  $var:ident $({ $( $(#[$attr:meta])* $field:ident: $ty:ty),* $(,)? })? $(( $( $(#[$attr2:meta])* $ty2:ty),* $(,)? ))? )* } },
-        { $($init_block:stmt)* },
-        { $headers:expr },
-        { $($init:expr => $expected:expr,)* }
-    ) => {
-        #[allow(dead_code, unused_imports)]
-        #[test]
-        fn $test_name() {
-            $($init_block)*
-
-            #[derive(Tabled)]
-            $(#[$struct_attr])*
-            enum TestType {
-                $(
-                    $(#[$var_attr])*
-                    $var $({
-                        $( $(#[$attr])* $field: $ty,)*
-                    })?
-
-                    $((
-                        $( $(#[$attr2])* $ty2,)*
-                    ))?
-                ),*
-            }
-
-            let headers: Vec<&'static str> = $headers.to_vec();
-            assert_eq!(TestType::headers(), headers);
-            assert_eq!(<TestType as Tabled>::LENGTH, headers.len());
-
-            {
-                use TestType::*;
-                $(
-                    let variant = $init;
-                    let fields: Vec<&'static str> = $expected.to_vec();
-                    assert_eq!(variant.fields(), fields);
-                )*
-            }
-        }
-    };
-}
-
-macro_rules! test_struct {
-    (
-        $test_name:ident,
-        { $(#[$struct_attr:meta])* { $( $(#[$attr:meta])* $field:ident: $ty:ty),* $(,)? } } $(,)?
-        { $($init_block:stmt)* } $(,)?
-        { $( $val_field:ident: $val:expr),* } $(,)?
-        { $headers:expr, $fields:expr $(,)? }  $(,)?
-    ) => {
-
-        #[allow(dead_code, unused_imports)]
-        #[test]
-        fn $test_name() {
-            $($init_block)*
-
-            #[derive(Tabled)]
-            $(#[$struct_attr])*
-            struct TestType {
-                $(
-                    $(#[$attr])*
-                    $field: $ty,
-                )*
-            }
-
-            let value = TestType {
-                $($val_field: $val,)*
-            };
-
-            let fields: Vec<&'static str> = $fields.to_vec();
-            let headers: Vec<&'static str> = $headers.to_vec();
-            assert_eq!(TestType::headers(), headers);
-            assert_eq!(value.fields(), fields);
-            assert_eq!(<TestType as Tabled>::LENGTH, headers.len());
-            assert_eq!(<TestType as Tabled>::LENGTH, fields.len());
-        }
-    };
-}
-
-#[allow(non_camel_case_types)]
-type sstr = &'static str;
-
-mod tuple {
-    use super::*;
-
-    test_tuple!(basic, { { u8 sstr } }, { 0 "v2" }, { ["0", "1"], ["0", "v2"] } );
-    test_tuple!(empty, { { } }, { }, { [], [] });
-
-    test_tuple!(rename, { { u8 #[tabled(rename = "field 2")] sstr } }, { 0 "123" }, { ["0", "field 2"], ["0", "123"] });
-
-    test_tuple!(skip_0, { { #[tabled(skip)] u8 #[tabled(rename = "field 2", skip)] sstr sstr } },           { 0 "v2" "123" }, { ["2"], ["123"] });
-    test_tuple!(skip_1, { { #[tabled(skip)] u8 #[tabled(skip)] #[tabled(rename = "field 2")] sstr sstr } }, { 0 "v2" "123" }, { ["2"], ["123"] });
-
-    test_tuple!(order_0,  { { #[tabled(order = 0)] u8 u8 u8} },                                           { 0 1 2 }, { ["0", "1", "2"], ["0", "1", "2"] });
-    test_tuple!(order_1,  { { #[tabled(order = 1)] u8 u8 u8} },                                           { 0 1 2 }, { ["1", "0", "2"], ["1", "0", "2"] });
-    test_tuple!(order_2,  { { #[tabled(order = 2)] u8 u8 u8} },                                           { 0 1 2 }, { ["1", "2", "0"], ["1", "2", "0"] });
-    test_tuple!(order_3,  { { u8 #[tabled(order = 0)] u8 u8} },                                           { 0 1 2 }, { ["1", "0", "2"], ["1", "0", "2"] });
-    test_tuple!(order_4,  { { u8 #[tabled(order = 1)] u8 u8} },                                           { 0 1 2 }, { ["0", "1", "2"], ["0", "1", "2"] });
-    test_tuple!(order_5,  { { u8 #[tabled(order = 2)] u8 u8} },                                           { 0 1 2 }, { ["0", "2", "1"], ["0", "2", "1"] });
-    test_tuple!(order_6,  { { u8 u8 #[tabled(order = 0)] u8} },                                           { 0 1 2 }, { ["2", "0", "1"], ["2", "0", "1"] });
-    test_tuple!(order_7,  { { u8 u8 #[tabled(order = 1)] u8} },                                           { 0 1 2 }, { ["0", "2", "1"], ["0", "2", "1"] });
-    test_tuple!(order_8,  { { u8 u8 #[tabled(order = 2)] u8} },                                           { 0 1 2 }, { ["0", "1", "2"], ["0", "1", "2"] });
-    test_tuple!(order_9,  { { #[tabled(order = 2)] u8 u8 #[tabled(order = 0)] u8} },                      { 0 1 2 }, { ["2", "1", "0"], ["2", "1", "0"] });
-    test_tuple!(order_10, { { #[tabled(order = 2)] u8 #[tabled(order = 1)] u8 u8} },                      { 0 1 2 }, { ["2", "1", "0"], ["2", "1", "0"] });
-    test_tuple!(order_11, { { #[tabled(order = 2)] u8 #[tabled(order = 2)] u8 #[tabled(order = 1)] u8} }, { 0 1 2 }, { ["0", "2", "1"], ["0", "2", "1"] });
-    test_tuple!(order_12, { { #[tabled(order = 2)] u8 #[tabled(order = 2)] u8 #[tabled(order = 2)] u8} }, { 0 1 2 }, { ["0", "1", "2"], ["0", "1", "2"] });
-    test_tuple!(order_13, { { #[tabled(order = 1)] u8 #[tabled(order = 1)] u8 #[tabled(order = 1)] u8} }, { 0 1 2 }, { ["0", "2", "1"], ["0", "2", "1"] });
-    test_tuple!(order_14, { { #[tabled(order = 2)] u8 #[tabled(order = 1)] u8 #[tabled(order = 0)] u8} }, { 0 1 2 }, { ["2", "1", "0"], ["2", "1", "0"] });
-
-    test_tuple!(rename_all, { #[tabled(rename_all = "UPPERCASE")] { u8 sstr } }, { 0 "123" }, { ["0", "1"], ["0", "123"] });
-
-    test_tuple!(rename_all_field, { { u8 #[tabled(rename_all = "UPPERCASE")] sstr } },                                                  { 0 "123" }, { ["0", "1"], ["0", "123"] });
-    test_tuple!(rename_all_field_with_rename_0, { { u8 #[tabled(rename_all = "UPPERCASE", rename = "Something")] sstr } },              { 0 "123" }, { ["0", "Something"], ["0", "123"] });
-    test_tuple!(rename_all_field_with_rename_1, { { u8 #[tabled(rename = "Something")] #[tabled(rename_all = "UPPERCASE")] sstr } },    { 0 "123" }, { ["0", "Something"], ["0", "123"] });
-
-    test_tuple!(
-        display_option,
-        { { u8 #[tabled(display = "display_option")] Option<sstr> } },
-        { 0 Some("v2") },
-        { ["0", "1"], ["0", "some v2"] },
-        pre: {
-            fn display_option(o: &Option<sstr>) -> String {
-                match o {
-                    Some(s) => format!("some {s}"),
-                    None => "none".to_string(),
-                }
-            }
-        }
-    );
-
-    test_tuple!(
-        display_option_args,
-        { { u8 #[tabled(display("display_option", 1, "234"))] Option<sstr> } },
-        { 0 Some("v2") },
-        { ["0", "1"], ["0", "some 1 234"] },
-        pre: {
-            fn display_option(_opt: &Option<sstr>, val: usize, text: &str) -> String {
-                format!("some {val} {text}")
-            }
-        }
-    );
-
-    test_tuple!(
-        display_option_self,
-        { { u8 #[tabled(display = "Self::display_option")] Option<sstr> } },
-        { 0 Some("v2") },
-        { ["0", "1"], ["0", "some v2"] },
-        pre: {
-            impl TestType {
-                fn display_option(o: &Option<sstr>) -> String {
-                    match o {
-                        Some(s) => format!("some {s}"),
-                        None => "none".to_string(),
-                    }
-                }
-            }
-        }
-    );
-
-    test_tuple!(
-        display_option_self_2,
-        { { u8 #[tabled(display("Self::display_option", self))] Option<sstr> } },
-        { 0 Some("v2") },
-        { ["0", "1"], ["0", "some v2"] },
-        pre: {
-            impl TestType {
-                fn display_option(_opt: &Option<sstr>, o: &TestType) -> String {
-                    match o.1 {
-                        Some(s) => format!("some {s}"),
-                        None => "none".to_string(),
-                    }
-                }
-            }
-        }
-    );
-
-    test_tuple!(
-        display_option_self_3,
-        { { u8 #[tabled(display("display_option", self))] Option<sstr> } },
-        { 0 Some("v2") },
-        { ["0", "1"], ["0", "some v2"] },
-        pre: {
-            fn display_option(_opt: &Option<sstr>, o: &TestType) -> String {
-                match o.1 {
-                    Some(s) => format!("some {s}"),
-                    None => "none".to_string(),
-                }
-            }
-        }
-    );
-
-    test_tuple!(
-        display_option_self_4,
-        { { u8 #[tabled(display("display_option", self.0, self.0))] Option<sstr> } },
-        { 0 Some("v2") },
-        { ["0", "1"], ["0", "some 0.0"] },
-        pre: {
-            fn display_option(_opt: &Option<sstr>, o1: u8, o2: u8) -> String {
-                format!("some {o1}.{o2}")
-            }
-        }
-    );
-
-    test_tuple!(format_1, { { u8 #[tabled(format = "foo {}")] sstr } },                                         { 0 "v2" },                     { ["0", "1"], ["0", "foo v2"] });
-    test_tuple!(format_2, { { u8 #[tabled(format = "foo {:?}")] sstr } },                                       { 0 "v2" },                     { ["0", "1"], ["0", "foo \"v2\""] });
-    // todo : self represents the tuple here. It should be the sstr element instead.
-    test_tuple!(format_3, { #[derive(Debug)] { u8 #[tabled(format("foo {} {:?}", 2, self))] String } },         { 0 String::from("string") },   { ["0", "1"], ["0", "foo 2 TestType(0, \"string\")"] });
-
-    // #[test]
-    // fn order_compile_fail_when_order_is_bigger_then_count_fields() {
-    //     #[derive(Tabled)]
-    //     struct St(#[tabled(order = 3)] u8, u8, u8);
-    // }
-}
-
-mod enum_ {
-    use super::*;
-
-    test_enum!(
-        basic,
-        { { Security Embedded Frontend Unknown } },
-        {},
-        { ["Security", "Embedded", "Frontend", "Unknown"] },
-        {
-            Security => ["+", "", "", ""],
-            Embedded => ["", "+", "", ""],
-            Frontend => ["", "", "+", ""],
-            Unknown =>  ["", "", "", "+"],
-        }
-    );
-
-    test_enum!(
-        diverse,
-        { { A { a: u8, b: i32 } B(sstr) K } },
-        {},
-        { ["A", "B", "K"] },
-        {
-            A { a: 1, b: 2 } => ["+", "", ""],
-            B("") => ["", "+",  ""],
-            K => ["", "", "+"],
-        }
-    );
-
-    test_enum!(
-        rename_variant,
-        { { #[tabled(rename = "Variant 1")] A { a: u8, b: i32 } #[tabled(rename = "Variant 2")] B(sstr) K } },
-        {},
-        { ["Variant 1", "Variant 2", "K"] },
-        {
-            A { a: 1, b: 2 } => ["+", "", ""],
-            B("") => ["", "+",  ""],
-            K => ["", "", "+"],
-        }
-    );
-
-    test_enum!(
-        skip_variant,
-        { { A { a: u8, b: i32 } #[tabled(skip)] B(sstr) K } },
-        {},
-        { ["A", "K"] },
-        {
-            A { a: 1, b: 2 } => ["+", ""],
-            B("") => ["", ""],
-            K => ["", "+"],
-        }
-    );
-
-    test_enum!(
-        inline_variant,
-        {
-            {
-            #[tabled(inline("Auto::"))] Auto { #[tabled(rename = "mod")] model: sstr, engine: sstr }
-            #[tabled(inline)] Bikecycle( #[tabled(rename = "name")] sstr, #[tabled(inline)] Bike )
-            Skateboard
-            }
-        },
-        {
-            #[derive(Tabled)]
-            struct Bike { brand: sstr, price: f32 }
-        },
-        { ["Auto::mod", "Auto::engine", "name", "brand", "price", "Skateboard"] },
-        {
-            Skateboard => ["", "", "", "", "", "+"],
-            Auto { model: "Mini", engine: "v8" } => ["Mini", "v8", "", "", "", ""],
-            Bikecycle("A bike", Bike { brand: "Canyon", price: 2000.0 })=> ["", "", "A bike", "Canyon", "2000", ""],
-        }
-    );
-
-    test_enum!(
-        inline_field_with_display_function,
-        {
-            {
-                #[tabled(inline("backend::"))]
-                Backend {
-                    #[tabled(display = "display", rename = "name")]
-                    value: sstr
-                }
-                Frontend
-            }
-        },
-        {
-            fn display(_: sstr) -> String {
-                "asd".to_string()
-            }
-        },
-        { ["backend::name", "Frontend"] },
-        {
-            Backend { value: "123" } => ["asd", ""],
-            Frontend => ["", "+"],
-        }
-    );
-
-    test_enum!(
-        inline_field_with_display_self_function,
-        {
-            {
-                #[tabled(inline("backend::"))]
-                Backend {
-                    #[tabled()]
-                    #[tabled(display("display", self), rename = "name")]
-                    value: sstr
-                }
-                Frontend
-            }
-        },
-        {
-            fn display<T>(_opt: &sstr, _: &T) -> String {
-                "asd".to_string()
-            }
-        },
-        { ["backend::name", "Frontend"] },
-        {
-            Backend { value: "123" } => ["asd", ""],
-            Frontend => ["", "+"],
-        }
-    );
-
-    test_enum!(
-        with_display,
-        {
-            {
-                #[tabled(inline)]
-                A(
-                    #[tabled(display = "format::<4>")]
-                    sstr
-                )
-                B
-            }
-        },
-        {
-            fn format<const ID: usize>(_: sstr) -> String {
-                ID.to_string()
-            }
-        },
-        { ["0", "B"] },
-        {
-            A("") => ["4", ""],
-            B => ["", "+"],
-        }
-    );
-
-    test_enum!(
-        with_display_self,
-        {
-            {
-                #[tabled(inline)]
-                A(
-                    #[tabled(display("Self::format::<4>", self))]
-                    sstr
-                )
-                B
-            }
-        },
-        {
-            impl TestType {
-                fn format<const ID: usize>(_opt: &sstr, _: &Self) -> String {
-                    ID.to_string()
-                }
-            }
-        },
-        { ["0", "B"] },
-        {
-            A("") => ["4", ""],
-            B => ["", "+"],
-        }
-    );
-
-    test_enum!(
-        with_display_self_complex_0,
-        {
-            {
-                #[tabled(inline)]
-                A(
-                    #[tabled(display("Self::format::<4>", self, self.0))]
-                    sstr
-                )
-                B
-            }
-        },
-        {
-            impl TestType {
-                fn format<const ID: usize>(_opt: &sstr, _: &Self, _: sstr) -> String {
-                    ID.to_string()
-                }
-            }
-        },
-        { ["0", "B"] },
-        {
-            A("") => ["4", ""],
-            B => ["", "+"],
-        }
-    );
-
-    test_enum!(
-        with_display_self_complex_1,
-        {
-            {
-                #[tabled(inline)]
-                A{
-                    #[tabled(display("Self::format::<4>", self, self.asd))]
-                    asd: sstr
-                }
-                B
-            }
-        },
-        {
-            impl TestType {
-                fn format<const ID: usize>(_opt: &sstr, _: &Self, _: sstr) -> String {
-                    ID.to_string()
-                }
-            }
-        },
-        { ["asd", "B"] },
-        {
-            A { asd: "" } => ["4", ""],
-            B => ["", "+"],
-        }
-    );
-
-    test_enum!(
-        rename_all_variant,
-        {
-            {
-                #[tabled(rename_all = "snake_case")]
-                VariantName1 { a: u8, b: i32 }
-                #[tabled(rename_all = "UPPERCASE")]
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["variant_name1", "VARIANTNAME2", "K"] },
-        {}
-    );
-
-    test_enum!(
-        rename_all_enum,
-        {
-            #[tabled(rename_all = "snake_case")]
-            {
-                VariantName1 { a: u8, b: i32 }
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["variant_name1", "variant_name2", "k"] },
-        {}
-    );
-
-    test_enum!(
-        rename_all_enum_inherited_inside_struct_enum,
-        {
-            #[tabled(rename_all = "snake_case")]
-            {
-                #[tabled(inline)]
-                VariantName1 { some_field_1: u8, some_field_2: i32 }
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["some_field_1", "some_field_2", "variant_name2", "k"] },
-        {}
-    );
-
-    test_enum!(
-        rename_all_enum_inherited_inside_struct_override_by_rename_enum,
-        {
-            #[tabled(rename_all = "snake_case")]
-            {
-                #[tabled(inline)]
-                VariantName1 {
-                    #[tabled(rename = "f1")]
-                    some_field_1: u8,
-                    #[tabled(rename = "f2")]
-                    some_field_2: i32,
-                }
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["f1", "f2", "variant_name2", "k"] },
-        {}
-    );
-
-    test_enum!(
-        rename_all_enum_inherited_inside_struct_override_by_rename_all_enum,
-        {
-            #[tabled(rename_all = "snake_case")]
-            {
-                #[tabled(inline)]
-                VariantName1 {
-                    #[tabled(rename_all = "UPPERCASE")]
-                    some_field_1: u8,
-                    #[tabled(rename_all = "CamelCase")]
-                    some_field_2: i32,
-                }
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["SOMEFIELD1", "someField2", "variant_name2", "k"] },
-        {}
-    );
-
-    test_enum!(
-        rename_all_variant_inherited_inside_struct_enum,
-        {
-            #[tabled(rename_all = "snake_case")]
-            {
-                #[tabled(inline)]
-                #[tabled(rename_all = "snake_case")]
-                VariantName1 {
-                    some_field_1: u8,
-                    some_field_2: i32,
-                }
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["some_field_1", "some_field_2", "variant_name2", "k"] },
-        {}
-    );
-
-    test_enum!(
-        rename_all_variant_inherited_inside_struct_enum_overridden_by_rename,
-        {
-            #[tabled(rename_all = "snake_case")]
-            {
-                #[tabled(inline, rename_all = "snake_case")]
-                VariantName1 {
-                    #[tabled(rename = "f1")]
-                    some_field_1: u8,
-                    #[tabled(rename = "f2")]
-                    some_field_2: i32,
-                }
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["f1", "f2", "variant_name2", "k"] },
-        {}
-    );
-
-    test_enum!(
-        rename_all_variant_inherited_inside_struct_override_by_rename_all_enum,
-        {
-            #[tabled(rename_all = "snake_case")]
-            {
-                #[tabled(rename_all = "snake_case", inline)]
-                VariantName1 {
-                    #[tabled(rename_all = "UPPERCASE")]
-                    some_field_1: u8,
-                    #[tabled(rename_all = "CamelCase")]
-                    some_field_2: i32,
-                }
-                VariantName2(String)
-                K
-            }
-        },
-        {},
-        { ["SOMEFIELD1", "someField2", "variant_name2", "k"] },
-        {}
-    );
-
-    test_enum!(
-        inline_enum_as_whole,
-        {
-            #[tabled(inline)] {
-                AbsdEgh { a: u8, b: i32 }
-                B(String)
-                K
-            }
-        },
-        {},
-        { ["TestType"] },
-        {
-            AbsdEgh { a: 0, b: 0 }  => ["AbsdEgh"],
-            B(String::new()) => ["B"],
-            K => ["K"],
-        }
-    );
-
-    test_enum!(
-        inline_enum_as_whole_and_rename,
-        {
-            #[tabled(inline, rename_all = "snake_case")]
-            {
-                AbsdEgh { a: u8, b: i32 }
-                B(String)
-                K
-            }
-        },
-        {},
-        { ["TestType"] },
-        {
-            AbsdEgh { a: 0, b: 0 }  => ["absd_egh"],
-            B(String::new()) => ["b"],
-            K => ["k"],
-        }
-    );
-
-    test_enum!(
-        inline_enum_as_whole_and_rename_inner,
-        {
-            #[tabled(inline)]
-            {
-                #[tabled(rename_all = "snake_case")]
-                AbsdEgh { a: u8, b: i32 }
-                #[tabled(rename_all = "lowercase")]
-                B(String)
-                K
-            }
-        },
-        {},
-        { ["TestType"] },
-        {
-            AbsdEgh { a: 0, b: 0 }  => ["absd_egh"],
-            B(String::new()) => ["b"],
-            K => ["K"],
-        }
-    );
-
-    test_enum!(
-        inline_enum_name,
-        {
-            #[tabled(inline("A struct name"))]
-            {
-                AbsdEgh { a: u8, b: i32 }
-                B(String)
-                K
-            }
-        },
-        {},
-        { ["A struct name"] },
-        {
-            AbsdEgh { a: 0, b: 0 }  => ["AbsdEgh"],
-            B(String::new()) => ["B"],
-            K => ["K"],
-        }
-    );
-
-    test_enum!(
-        enum_display_with_variant,
-        {
-            {
-                #[tabled(display = "display_variant1")]
-                AbsdEgh { a: u8, b: i32 }
-                #[tabled(display = "display_variant2::<200>")]
-                B(String)
-                K
-            }
-        },
-        {
-            fn display_variant1(_: &TestType) -> &'static str {
-                "Hello World"
-            }
-
-            fn display_variant2<const VAL: usize>(_: &TestType) -> String {
-                format!("asd {VAL}")
-            }
-        },
-        { ["AbsdEgh", "B", "K"] },
-        {
-            AbsdEgh { a: 0, b: 0 }  => ["Hello World", "", ""],
-            B(String::new()) => ["", "asd 200", ""],
-            K => ["", "", "+"],
-        }
-    );
-
-    test_enum!(
-        enum_display_with_self_variant,
-        {
-            {
-                #[tabled(display("display_variant1", self))]
-                AbsdEgh { a: u8, b: i32 }
-                #[tabled(display("display_variant2::<200, _>", self))]
-                B(String)
-                K
-            }
-        },
-        {
-            fn display_variant1<D>(_: &TestType, _: &D) -> &'static str {
-                "Hello World"
-            }
-
-            fn display_variant2<const VAL: usize, D>(_: &TestType, _: &D) -> String {
-                format!("asd {VAL}")
-            }
-        },
-        { ["AbsdEgh", "B", "K"] },
-        {
-            AbsdEgh { a: 0, b: 0 }  => ["Hello World", "", ""],
-            B(String::new()) => ["", "asd 200", ""],
-            K => ["", "", "+"],
-        }
-    );
-
-    test_enum!(
-        enum_display_with_arguments,
-        {
-            {
-                #[tabled(display("display1", 1, 2, self))]
-                AbsdEgh { a: u8, b: i32 }
-                #[tabled(display("display2::<200>", "Hello World"))]
-                B(String)
-                #[tabled(display("display1", 100, 200, self))]
-                K
-            }
-        },
-        {
-            fn display1<D>(_: &TestType, val: usize, val2: usize, _: &D) -> String {
-                format!("{val} {val2}")
-            }
-
-            fn display2<const VAL: usize>(_: &TestType, val: &str) -> String {
-                format!("asd {VAL} {val}")
-            }
-        },
-        { ["AbsdEgh", "B", "K"] },
-        {
-            AbsdEgh { a: 0, b: 0 }  => ["1 2", "", ""],
-            B(String::new()) => ["", "asd 200 Hello World", ""],
-            K => ["", "", "100 200"],
-        }
-    );
-
-    test_enum!(order_0,  { { #[tabled(order = 0)] V1(u8) V2(u8) V3(u8) } },                                               {}, { ["V1", "V2", "V3"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
-    test_enum!(order_1,  { { #[tabled(order = 1)] V1(u8) V2(u8) V3(u8) } },                                               {}, { ["V2", "V1", "V3"] }, { V1(0) => ["", "+", ""], V2(0) => ["+", "", ""], V3(0) => ["", "", "+"],});
-    test_enum!(order_2,  { { #[tabled(order = 2)] V1(u8) V2(u8) V3(u8) } },                                               {}, { ["V2", "V3", "V1"] }, { V1(0) => ["", "", "+"], V2(0) => ["+", "", ""], V3(0) => ["", "+", ""],});
-    test_enum!(order_3,  { { V1(u8) #[tabled(order = 0)] V2(u8) V3(u8) } },                                               {}, { ["V2", "V1", "V3"] }, { V1(0) => ["", "+", ""], V2(0) => ["+", "", ""], V3(0) => ["", "", "+"],});
-    test_enum!(order_4,  { { V1(u8) #[tabled(order = 1)] V2(u8) V3(u8) } },                                               {}, { ["V1", "V2", "V3"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
-    test_enum!(order_5,  { { V1(u8) #[tabled(order = 2)] V2(u8) V3(u8) } },                                               {}, { ["V1", "V3", "V2"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
-    test_enum!(order_6,  { { V1(u8) V2(u8) #[tabled(order = 0)] V3(u8) } },                                               {}, { ["V3", "V1", "V2"] }, { V1(0) => ["", "+", ""], V2(0) => ["", "", "+"], V3(0) => ["+", "", ""],});
-    test_enum!(order_7,  { { V1(u8) V2(u8) #[tabled(order = 1)] V3(u8) } },                                               {}, { ["V1", "V3", "V2"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
-    test_enum!(order_8,  { { V1(u8) V2(u8) #[tabled(order = 2)] V3(u8) } },                                               {}, { ["V1", "V2", "V3"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
-    test_enum!(order_9,  { { #[tabled(order = 2)] V1(u8) V2(u8) #[tabled(order = 0)] V3(u8) } },                          {}, { ["V3", "V2", "V1"] }, { V1(0) => ["", "", "+"], V2(0) => ["", "+", ""], V3(0) => ["+", "", ""],});
-    test_enum!(order_10, { { #[tabled(order = 2)] V1(u8) V2(u8) #[tabled(order = 1)] V3(u8) } },                          {}, { ["V2", "V3", "V1"] }, { V1(0) => ["", "", "+"], V2(0) => ["+", "", ""], V3(0) => ["", "+", ""],});
-    test_enum!(order_11, { { #[tabled(order = 2)] V1(u8) #[tabled(order = 2)] V2(u8) #[tabled(order = 1)] V3(u8) } },     {}, { ["V1", "V3", "V2"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
-    test_enum!(order_12, { { #[tabled(order = 2)] V1(u8) #[tabled(order = 1)] V2(u8) #[tabled(order = 0)] V3(u8) } },     {}, { ["V3", "V2", "V1"] }, { V1(0) => ["", "", "+"], V2(0) => ["", "+", ""], V3(0) => ["+", "", ""],});
-    test_enum!(order_13, { { #[tabled(order = 0)] V1(u8) #[tabled(order = 0)] V2(u8) #[tabled(order = 0)] V3(u8) } },     {}, { ["V3", "V1", "V2"] }, { V1(0) => ["", "+", ""], V2(0) => ["", "", "+"], V3(0) => ["+", "", ""],});
-    test_enum!(order_14, { { #[tabled(order = 1)] V1(u8) #[tabled(order = 1)] V2(u8) #[tabled(order = 1)] V3(u8) } },     {}, { ["V1", "V3", "V2"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
-    test_enum!(order_15, { { #[tabled(order = 2)] V1(u8) #[tabled(order = 2)] V2(u8) #[tabled(order = 2)] V3(u8) } },     {}, { ["V1", "V2", "V3"] }, { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
-
-    test_enum!(order_0_inlined, { #[tabled(inline)] { #[tabled(order = 1)] V1(u8) V2(u8) V3(u8) } }, {}, { ["TestType"] }, { V1(0) => ["V1"], V2(0) => ["V2"], V3(0) => ["V3"], });
-
-    test_enum!(
-        format,
-        {
-            {
-                #[tabled(inline)]
-                AbsdEgh {
-                    #[tabled(format("{}-{}", self.a, self.b))]
-                    a: u8,
-                    b: i32
-                }
-                #[tabled(format("{} s", 4))]
-                B(String)
-                #[tabled(inline)]
-                C(
-                    #[tabled(rename = "C", format("{} ss", 4))]
-                    String
-                )
-                #[tabled(format = "k.")]
-                K
-            }
-        },
-        {},
-        { ["a", "b", "B", "C", "K"] },
-        {
-            AbsdEgh { a: 0, b: 1 }  => ["0-1", "1", "", "", ""],
-            B(String::new()) => ["",  "", "4 s", "", ""],
-            C(String::new()) => ["", "",  "", "4 ss", ""],
-            K => ["", "", "",  "", "k."],
-        }
-    );
-
-    test_enum!(
-        format_complex,
-        {
-            {
-                #[tabled(inline)]
-                AbsdEgh {
-                    #[tabled(format("{}-{}-{}", foo(*self.a as usize), foo(*self.b as usize), self.c[2]))]
-                    a: u8,
-                    b: i32,
-                    #[tabled(skip)]
-                    c: Vec<usize>,
-                }
-                #[tabled(format("{} s", foo(4)))]
-                B(String)
-                #[tabled(inline)]
-                C(
-                    #[tabled(rename = "C", format("{} ss {}", foo(4), self.1[2]))]
-                    String,
-                    #[tabled(skip)]
-                    Vec<usize>,
-                )
-                #[tabled(format = "k.")]
-                K
-            }
-        },
-        {
-            fn foo(a: usize) -> String {
-                if a > 100 {
-                    String::from(">100")
-                } else {
-                    String::from("<100")
-                }
-            }
-        },
-        { ["a", "b", "B", "C", "K"] },
-        {
-            AbsdEgh { a: 0, b: 1, c: vec![1, 2, 3] }  => ["<100-<100-3", "1", "", "", ""],
-            B(String::new()) => ["",  "", "<100 s", "", ""],
-            C(String::new(), vec![1, 2, 3]) => ["", "",  "", "<100 ss 3", ""],
-            K => ["", "", "",  "", "k."],
-        }
-    );
-}
-
-mod unit {
-    use super::*;
+test_tuple!(
+    tuple_empty,
+    declare: { { } }
+    init: {}
+    define: { }
+    assert_headers: { [] }
+    assert_fields: { [] }
+);
 
-    #[test]
-    fn basic() {
-        #[derive(Tabled)]
-        struct St;
-        let st = St;
+test_tuple!(
+    tuple_basic,
+    declare: { { u32 sstr } }
+    init: {}
+    define: { 20202503 "Hello World" }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["20202503", "Hello World"] }
+);
 
-        assert!(st.fields().is_empty());
-        assert!(St::headers().is_empty());
-        assert_eq!(St::LENGTH, 0);
+test_enum!(
+    enum_basic,
+    declare: { { Security Embedded Frontend Unknown } }
+    init: {}
+    assert_headers: { ["Security", "Embedded", "Frontend", "Unknown"] }
+    assert: {
+        Security => ["+", "", "", ""],
+        Embedded => ["", "+", "", ""],
+        Frontend => ["", "", "+", ""],
+        Unknown =>  ["", "", "", "+"],
     }
-}
-
-mod structure {
-    use super::*;
-
-    test_struct!(empty, { {} } {} { } { [], [] });
-    test_struct!(
-        general,
-        {
-            {
-                f1: u8,
-                f2: sstr,
-            }
-        }
-        {}
-        { f1: 0, f2: "v2" }
-        {
-            ["f1", "f2"],
-            ["0", "v2"],
-        }
-    );
-    test_struct!(
-        rename,
-        {
-            {
-                #[tabled(rename = "field 1")]
-                f1: u8,
-                #[tabled(rename = "field 2")]
-                f2: sstr,
-            }
-        }
-        {}
-        { f1: 0, f2: "v2" }
-        {
-            ["field 1", "field 2"],
-            ["0", "v2"],
-        }
-    );
-    test_struct!(
-        skip,
-        {
-            {
-                #[tabled(skip)]
-                f1: u8,
-                #[tabled(rename = "field 2", skip)]
-                f2: sstr,
-                f3: sstr,
-            }
-        }
-        {}
-        { f1: 0, f2: "v2", f3: "123" }
-        {
-            ["f3"],
-            ["123"],
-        }
-    );
-    test_struct!(
-        skip_true,
-        {
-            {
-                #[tabled(skip = true)]
-                f1: u8,
-                #[tabled(rename = "field 2", skip = true)]
-                f2: sstr,
-                f3: sstr,
-            }
-        }
-        {}
-        { f1: 0, f2: "v2", f3: "123" }
-        {
-            ["f3"],
-            ["123"],
-        }
-    );
-    test_struct!(
-        inline,
-        {
-            {
-                #[tabled(inline = true)]
-                id: u8,
-                name: sstr,
-                #[tabled(inline)]
-                ed: Education
-            }
-        }
-        {
-            #[derive(Tabled)]
-            struct Education { uni: sstr, graduated: bool }
-        }
-        {
-            id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }
-        }
-        {
-            ["u8", "name","uni","graduated"],
-            ["0", "Maxim", "BNTU", "true"]
-        }
-    );
-    test_struct!(
-        inline_with_prefix,
-        {
-            {
-                #[tabled(rename = "it's an ignored option", inline)]
-                id: u8,
-                name: sstr,
-                #[tabled(inline("education::"))]
-                ed: Education,
-            }
-        }
-        {
-            #[derive(Tabled)]
-            struct Education { uni: sstr, graduated: bool }
-        }
-        {
-            id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }}
-        {
-            ["u8", "name","education::uni","education::graduated"],
-            ["0", "Maxim", "BNTU", "true"]
-        }
-    );
-    test_struct!(
-        display_with,
-        {
-            {
-                f1: u8,
-                #[tabled(display = "display_option")]
-                f2: Option<sstr>,
-            }
-        }
-        {
-            fn display_option(o: &Option<sstr>) -> String {
-                match o {
-                    Some(s) => format!("some {s}"),
-                    None => "none".to_string(),
-                }
-            }
-        }
-        { f1: 0, f2: Some("v2") }
-        { ["f1", "f2"], ["0", "some v2"] }
-    );
-    test_struct!(
-        display_with_args,
-        {
-            {
-                f1: u8,
-                #[tabled(display("display_option", 1, 2, 3))]
-                f2: Option<sstr>,
-            }
-        }
-        {
-            fn display_option(_opt: &Option<sstr>, v1: usize, v2: usize, v3: usize) -> String {
-                format!("{v1} {v2} {v3}")
-            }
-        }
-        { f1: 0, f2: Some("v2") }
-        { ["f1", "f2"], ["0", "1 2 3"] }
-    );
-    test_struct!(
-        display_with_args_using_self,
-        {
-            {
-                f1: u8,
-                #[tabled(display("display_option", &self.f1, 2, 3))]
-                f2: Option<sstr>,
-            }
-        }
-        {
-            fn display_option(_opt: &Option<sstr>, v1: &u8, v2: usize, v3: usize) -> String {
-                format!("{v1} {v2} {v3}")
-            }
-        }
-        { f1: 0, f2: Some("v2") }
-        { ["f1", "f2"], ["0", "0 2 3"] }
-    );
-    test_struct!(
-        display_with_self_static_method,
-        {
-            {
-                f1: u8,
-                #[tabled(display = "Self::display_option")]
-                f2: Option<sstr>,
-            }
-        }
-        {
-            impl TestType {
-                fn display_option(o: &Option<sstr>) -> String {
-                    match o {
-                        Some(s) => format!("some {s}"),
-                        None => "none".to_string(),
-                    }
-                }
-            }
-        }
-        { f1: 0, f2: Some("v2") }
-        { ["f1", "f2"], ["0", "some v2"] }
-    );
-    test_struct!(
-        display_with_self_static_method_2,
-        {
-            {
-                f1: u8,
-                #[tabled(display("Self::display_option", self))]
-                f2: Option<sstr>,
-            }
-        }
-        {
-            impl TestType {
-                fn display_option(_opt: &Option<sstr>, o: &TestType) -> String {
-                    match o.f2 {
-                        Some(s) => format!("some {s}"),
-                        None => "none".to_string(),
-                    }
-                }
-            }
-        }
-        { f1: 0, f2: Some("v2") }
-        { ["f1", "f2"], ["0", "some v2"] }
-    );
-    test_struct!(
-        display_with_self_2_self_static_method_2,
-        {
-            {
-                f1: u8,
-                #[tabled(display("Self::display_option", self))]
-                f2: Option<sstr>,
-            }
-        }
-        {
-            impl TestType {
-                fn display_option(_opt: &Option<sstr>, s: &Self) -> String {
-                    match s.f2 {
-                        Some(s) => format!("some {s}"),
-                        None => "none".to_string(),
-                    }
-                }
-            }
-        }
-        { f1: 0, f2: Some("v2") }
-        { ["f1", "f2"], ["0", "some v2"] }
-    );
-    test_struct!(
-        display_with_self_2_self_static_method,
-        {
-            {
-                f1: u8,
-                #[tabled(display("display_option", self))]
-                f2: Option<sstr>,
-            }
-        }
-        {
-            fn display_option(_opt: &Option<sstr>, o: &TestType) -> String {
-                match o.f2 {
-                    Some(s) => format!("some {s}"),
-                    None => "none".to_string(),
-                }
-            }
-        }
-        { f1: 0, f2: Some("v2") }
-        { ["f1", "f2"], ["0", "some v2"] }
-    );
-    test_struct!(
-        display_with_args_using_self_array_and_func,
-        {
-            {
-                #[tabled(skip)]
-                f1: [u8; 4],
-                #[tabled(display("display_option", &[self.f1[0], self.f1[1]], ToString::to_string(&self.f3.to_string())))]
-                f2: Option<sstr>,
-                f3: usize,
-            }
-        }
-        {
-            fn display_option(_opt: &Option<sstr>, v1: &[u8; 2], v4: String) -> String {
-                format!("{} {} {v4}", v1[0], v1[1])
-            }
-        }
-        { f1: [0, 1, 2, 3], f2: Some("v2"), f3: 100 }
-        { ["f2", "f3"], ["0 1 100", "100"] }
-    );
-    test_struct!(order_0,  { { #[tabled(order = 0)] f0: u8, f1: u8, f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f0", "f1", "f2"], ["0", "1", "2"] });
-    test_struct!(order_1,  { { #[tabled(order = 1)] f0: u8, f1: u8, f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f1", "f0", "f2"], ["1", "0", "2"] });
-    test_struct!(order_2,  { { #[tabled(order = 2)] f0: u8, f1: u8, f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f1", "f2", "f0"], ["1", "2", "0"] });
-    test_struct!(order_3,  { { f0: u8, #[tabled(order = 0)] f1: u8, f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f1", "f0", "f2"], ["1", "0", "2"] });
-    test_struct!(order_4,  { { f0: u8, #[tabled(order = 1)] f1: u8, f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f0", "f1", "f2"], ["0", "1", "2"] });
-    test_struct!(order_5,  { { f0: u8, #[tabled(order = 2)] f1: u8, f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f0", "f2", "f1"], ["0", "2", "1"] });
-    test_struct!(order_6,  { { f0: u8, f1: u8, #[tabled(order = 0)] f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f2", "f0", "f1"], ["2", "0", "1"] });
-    test_struct!(order_7,  { { f0: u8, f1: u8, #[tabled(order = 1)] f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f0", "f2", "f1"], ["0", "2", "1"] });
-    test_struct!(order_8,  { { f0: u8, f1: u8, #[tabled(order = 2)] f2: u8 } }                                           {} { f0: 0, f1: 1, f2: 2 } { ["f0", "f1", "f2"], ["0", "1", "2"] });
-    test_struct!(order_9,  { { #[tabled(order = 2)] f0: u8, f1: u8, #[tabled(order = 0)] f2: u8 } }                      {} { f0: 0, f1: 1, f2: 2 } { ["f2", "f1", "f0"], ["2", "1", "0"] });
-    test_struct!(order_10, { { #[tabled(order = 2)] f0: u8, #[tabled(order = 1)] f1: u8, f2: u8 } }                      {} { f0: 0, f1: 1, f2: 2 } { ["f2", "f1", "f0"], ["2", "1", "0"] });
-    test_struct!(order_11, { { #[tabled(order = 2)] f0: u8, #[tabled(order = 2)] f1: u8, #[tabled(order = 1)] f2: u8 } } {} { f0: 0, f1: 1, f2: 2 } { ["f0", "f2", "f1"], ["0", "2", "1"] });
-    test_struct!(order_12, { { #[tabled(order = 2)] f0: u8, #[tabled(order = 1)] f1: u8, #[tabled(order = 0)] f2: u8 } } {} { f0: 0, f1: 1, f2: 2 } { ["f2", "f1", "f0"], ["2", "1", "0"] });
-
-    test_struct!(
-        rename_all,
-        { #[tabled(rename_all = "UPPERCASE")] { f1: u8, f2: sstr } }
-        {}
-        { f1: 0, f2: "v2" }
-        { ["F1", "F2"], ["0", "v2"] }
-    );
-    test_struct!(
-        rename_all_override_in_field_by_rename,
-        { #[tabled(rename_all = "UPPERCASE")] { #[tabled(rename = "213213")] f1: u8, f2: sstr } }
-        {}
-        { f1: 0, f2: "v2" }
-        { ["213213", "F2"], ["0", "v2"] }
-    );
-    test_struct!(
-        rename_all_override_in_field_by_rename_all,
-        { #[tabled(rename_all = "UPPERCASE")] { #[tabled(rename_all = "lowercase")] f1: u8, f2: sstr } }
-        {}
-        { f1: 0, f2: "v2" }
-        { ["f1", "F2"], ["0", "v2"] }
-    );
-    test_struct!(
-        rename_all_field,
-        { { #[tabled(rename_all = "lowercase")] f1: u8, #[tabled(rename_all = "UPPERCASE")] f2: sstr } }
-        {}
-        { f1: 0, f2: "v2" }
-        { ["f1", "F2"], ["0", "v2"] }
-    );
-    test_struct!(
-        rename_all_field_overridden_by_rename,
-        { { #[tabled(rename_all = "lowercase", rename = "Hello")] f1: u8, #[tabled(rename_all = "UPPERCASE")] f2: sstr } }
-        {}
-        { f1: 0, f2: "v2" }
-        { ["Hello", "F2"], ["0", "v2"] }
-    );
+);
 
-    test_struct!(
-        format,
-        {
-            {
-                #[tabled(format = "{} cc")]
-                f1: u8,
-                f2: u8,
-            }
-        }
-        {}
-        { f1: 0, f2: 0 }
-        { ["f1", "f2"], ["0 cc", "0"] }
-    );
+test_enum!(
+    enum_diverse,
+    declare: { { A { a: u8, b: i32 } B(sstr) K } }
+    init: {}
+    assert_headers: { ["A", "B", "K"] }
+    assert: {
+        A { a: 1, b: 2 } => ["+", "", ""],
+        B("") => ["", "+",  ""],
+        K => ["", "", "+"],
+    }
+);
 
-    test_struct!(
-        format_with_args,
-        {
-            {
-                #[tabled(format("{}/{} cc/kg", self.f1, self.f2))]
-                f1: u8,
-                f2: u8,
-            }
-        }
-        {}
-        { f1: 1, f2: 2 }
-        { ["f1", "f2"], ["1/2 cc/kg", "2"] }
-    );
+#[test]
+fn basic() {
+    #[derive(Tabled)]
+    struct St;
+    let st = St;
 
-    // #[test]
-    // fn order_compile_fail_when_order_is_bigger_then_count_fields() {
-    //     #[derive(Tabled)]
-    //     struct St {
-    //         #[tabled(order = 3)]
-    //         f0: u8,
-    //         f1: u8,
-    //         f2: u8,
-    //     }
-    // }
+    assert!(st.fields().is_empty());
+    assert!(St::headers().is_empty());
+    assert_eq!(St::LENGTH, 0);
 }
 
-test_tuple!(skipped_fields_not_implement_display_tuple, { { #[tabled(skip)] () sstr } }, { () "123" }, { ["1"], ["123"] });
-test_struct!(skipped_fields_not_implement_display_struct, { { #[tabled(skip)] _unit: (), s: sstr } } {} { _unit: (), s: "123" } { ["s"], ["123"] });
 test_struct!(
-    skipped_fields_not_implement_display_struct_in_inline,
-    { { s: sstr, #[tabled(inline)] f: S1 } }
-    {
-        #[derive(Tabled)]
-        struct S1 {
-            #[tabled(skip)]
-            _unit: (),
-            s: sstr,
-        }
-    }
-    { s: "123", f: S1 { _unit: (), s: "..." } }
-    { ["s", "s"], ["123", "..."] },
+    struct_empty,
+    declare: { {} }
+    init: {}
+    define: { }
+    assert_headers: { [] }
+    assert_fields: { [] }
 );
-test_enum!(
-    skipped_fields_not_implement_display_enum,
-    {
+
+test_struct!(
+    struct_general,
+    declare: {
         {
-            #[tabled(inline("A::"))]
-            A {
-                name: sstr
-            }
-            #[tabled(inline("B::"))]
-            B {
-                issue: usize,
-                name: sstr,
-                #[tabled(skip)]
-                _gem: (),
-            }
-            #[tabled(inline("C::"))]
-            C(usize, #[tabled(skip)] (), sstr)
-            D
+            f1: u8,
+            f2: sstr,
         }
-    },
-    {},
-    { ["A::name", "B::issue", "B::name", "C::0", "C::2", "D"] },
-    {
-        A { name: "nrdxp" } => ["nrdxp", "", "", "", "", ""],
-        B { _gem: (), issue: 32, name: "nrdxp" } => ["", "32", "nrdxp", "", "", ""],
-        C(32, (), "nrdxp") => ["", "", "", "32", "nrdxp", ""],
-        D => ["", "", "", "", "", "+"],
     }
+    init: {}
+    define: { f1: 0, f2: "v2" }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "v2"] }
 );
 
-test_struct!(
-    ignore_display_with_when_used_with_inline,
-    { { f1: sstr, f2: sstr, #[tabled(display = "print", inline)] f3: usize } }
-    {}
-    { f1: "123", f2: "456", f3: 789 }
-    { ["f1", "f2", "usize"], ["123", "456", "789"], }
-);
-test_struct!(
-    ignore_display_with_when_used_with_inline_2,
-    { { f1: sstr, f2: sstr, #[tabled(display = "print", )] #[tabled(inline)] f3: usize } }
-    {}
-    { f1: "123", f2: "456", f3: 789 }
-    { ["f1", "f2", "usize"], ["123", "456", "789"], }
-);
-test_struct!(
-    display_with_and_rename,
-    { { f1: sstr, f2: sstr, #[tabled(display = "print", rename = "asd")] f3: usize } }
-    { #[allow(dead_code)] fn print<T>(_: T) -> String { String::new() } }
-    { f1: "123", f2: "456", f3: 789 }
-    { ["f1", "f2", "asd"], ["123", "456", ""], }
-);
-test_struct!(
-    display_with_and_rename_2,
-    { { f1: sstr, f2: sstr, #[tabled(display = "print")] #[tabled(rename = "asd")] f3: usize } }
-    { #[allow(dead_code)] fn print<T>(_: T) -> String { String::new() } }
-    { f1: "123", f2: "456", f3: 789 }
-    { ["f1", "f2", "asd"], ["123", "456", ""], }
-);
-test_struct!(
-    display_with_and_rename_all,
-    { { f1: sstr, f2: sstr, #[tabled(display = "print", rename_all = "UPPERCASE")] f3: usize } }
-    { #[allow(dead_code)] fn print<T>(_: T) -> String { String::new() } }
-    { f1: "123", f2: "456", f3: 789 }
-    { ["f1", "f2", "F3"], ["123", "456", ""], }
-);
-
-#[test]
-fn rename_all_variants() {
-    macro_rules! test_case {
-        ( $name:ident, $case:expr ) => {
-            #[allow(dead_code)]
-            #[derive(Tabled)]
-            #[tabled(rename_all = $case)]
-            struct $name {
-                field: usize,
-            }
-        };
+mod __ {
+    #[test]
+    fn dont_import_the_trait() {
+        #[derive(tabled::Tabled)]
+        struct __;
     }
-
-    test_case!(S1, "UPPERCASE");
-    test_case!(S2, "lowercase");
-    test_case!(S3, "camelCase");
-    test_case!(S4, "PascalCase");
-    test_case!(S5, "snake_case");
-    test_case!(S6, "SCREAMING_SNAKE_CASE");
-    test_case!(S7, "kebab-case");
-    test_case!(S8, "verbatimcase");
 }
 
+// TODO: MOVE TO UI
+// #[test]
+// fn order_compile_fail_when_order_is_bigger_then_count_fields() {
+//     #[derive(Tabled)]
+//     struct St(#[tabled(order = 3)] u8, u8, u8);
+// }
+
+// TODO: MOVE TO UI
+//
 // #[test]
 // fn wrong_rename_all_panic_when_used_as_not_first() {
 //     #[derive(Tabled)]
@@ -1399,501 +124,15 @@ fn rename_all_variants() {
 //     assert_eq!(st.fields(), vec!["789"]);
 // }
 
-#[test]
-fn rename_all_gets_last_value() {
-    #[derive(Tabled)]
-    #[tabled(rename_all = "UPPERCASE")]
-    #[tabled(rename_all = "PascalCase")]
-    struct Struct1 {
-        field: usize,
-    }
-
-    let st = Struct1 { field: 789 };
-
-    assert_eq!(Struct1::headers(), vec!["Field"],);
-    assert_eq!(st.fields(), vec!["789"]);
-
-    #[derive(Tabled)]
-    #[tabled(rename_all = "UPPERCASE", rename_all = "PascalCase")]
-    struct Struct2 {
-        field: usize,
-    }
-
-    let st = Struct2 { field: 789 };
-
-    assert_eq!(Struct1::headers(), vec!["Field"],);
-    assert_eq!(st.fields(), vec!["789"]);
-}
-
-#[test]
-fn test_order_skip_usage() {
-    #[derive(Tabled, Default)]
-    pub struct Example {
-        #[tabled(skip)]
-        #[allow(dead_code)]
-        id: usize,
-        name: String,
-        #[tabled(order = 0)]
-        details: String,
-    }
-
-    #[derive(Tabled, Default)]
-    pub struct Example2 {
-        #[tabled(skip)]
-        #[allow(dead_code)]
-        id: usize,
-        name: String,
-        #[tabled(order = 1)]
-        details: String,
-    }
-
-    assert_eq!(Example::headers(), vec!["details", "name"],);
-    assert_eq!(Example::default().fields(), vec!["", ""]);
-}
-
-#[test]
-fn test_skip_enum_0() {
-    #[allow(dead_code)]
-    #[derive(Tabled)]
-    enum Letters {
-        Vowels {
-            character: char,
-            lang: u8,
-        },
-        Consonant(char),
-        #[tabled(skip)]
-        Digit,
-    }
-
-    assert_eq!(Letters::headers(), vec!["Vowels", "Consonant"]);
-    assert_eq!(Letters::Consonant('c').fields(), vec!["", "+"]);
-    assert_eq!(Letters::Digit.fields(), vec!["", ""]);
-}
-
-#[test]
-fn test_reimport_trait_by_crate_attribute() {
-    pub mod new_module {
-        pub trait Tabled {
-            const LENGTH: usize;
-
-            fn fields(&self) -> Vec<std::borrow::Cow<'_, str>>;
-            fn headers() -> Vec<std::borrow::Cow<'static, str>>;
-        }
-    }
-
-    mod tabled {}
-
-    #[allow(dead_code)]
-    #[derive(Tabled)]
-    #[tabled(crate = "new_module")]
-    enum Letters {
-        Vowels {
-            character: char,
-            lang: u8,
-        },
-        Consonant(char),
-        #[tabled(skip)]
-        Digit,
-    }
-
-    assert_eq!(
-        <Letters as new_module::Tabled>::headers(),
-        vec!["Vowels", "Consonant"]
-    );
-    assert_eq!(
-        <Letters as new_module::Tabled>::fields(&Letters::Consonant('c')),
-        vec!["", "+"]
-    );
-    assert_eq!(
-        <Letters as new_module::Tabled>::fields(&Letters::Digit),
-        vec!["", ""]
-    );
-}
-
+// TODO: MOVE TO UI
+//
 // #[test]
-// fn test_display_with_2() {
+// fn order_compile_fail_when_order_is_bigger_then_count_fields() {
 //     #[derive(Tabled)]
-//     #[allow(dead_code)]
-//     struct Struct<'a> {
-//         #[tabled(display("std::path::Path::display"))]
-//         path: &'a std::path::Path,
+//     struct St {
+//         #[tabled(order = 3)]
+//         f0: u8,
+//         f1: u8,
+//         f2: u8,
 //     }
 // }
-
-#[test]
-fn test_format_enum_inline() {
-    #[derive(Tabled)]
-    enum Struct {
-        #[tabled(inline)]
-        Variant1 {
-            #[tabled(rename = "cccc")]
-            #[tabled(format("{} {}", self.character, self.lang))]
-            character: char,
-            lang: u8,
-        },
-        Variant2(char),
-        Variant3,
-    }
-
-    assert_eq!(Struct::headers(), ["cccc", "lang", "Variant2", "Variant3"]);
-    assert_eq!(
-        Struct::Variant1 {
-            character: 'c',
-            lang: b'c'
-        }
-        .fields(),
-        ["c 99", "99", "", ""]
-    );
-    assert_eq!(Struct::Variant2('c').fields(), ["", "", "+", ""]);
-    assert_eq!(Struct::Variant3.fields(), ["", "", "", "+"]);
-}
-
-#[test]
-#[allow(dead_code)]
-fn test_macros_in_display_with() {
-    #[derive(Tabled)]
-    #[tabled(rename_all = "camelCase")]
-    struct Country {
-        name: String,
-        #[tabled(display("display_capital", format!(".{}", self.capital)))]
-        capital: String,
-        #[tabled(display("display_perimeter", self))]
-        area_km2: f32,
-        #[tabled(display = "str::to_lowercase")]
-        national_currency: String,
-        national_currency_short: String,
-    }
-
-    fn display_perimeter(_area: &f32, country: &Country) -> sstr {
-        if country.area_km2 > 1_000_000.0 {
-            "Very Big Land"
-        } else {
-            "Big Land"
-        }
-    }
-
-    fn display_capital(_capital: &str, country: String) -> std::borrow::Cow<'static, str> {
-        format!("{country}!").into()
-    }
-}
-
-#[test]
-#[allow(dead_code)]
-fn test_macros_in_format() {
-    #[derive(Tabled)]
-    struct Country {
-        name: String,
-        #[tabled(format("{}", format!(".{}", self.capital)))]
-        capital: String,
-        #[tabled(format("{}", self.field1[0]))]
-        field1: [u8; 4],
-    }
-}
-
-#[test]
-#[allow(dead_code)]
-fn test_enum_format_1() {
-    #[derive(Tabled)]
-    struct User {
-        #[tabled(format("{}.{}.{}.{}", self.ip[0], self.ip[1], self.ip[2], self.ip[3]))]
-        ip: [u8; 4],
-        #[tabled(inline)]
-        password: Password,
-    }
-
-    #[derive(Tabled)]
-    enum Password {
-        #[tabled(inline)]
-        Mask {
-            #[tabled(format("t={}/{}", self.text, self.factor))]
-            text: String,
-            #[tabled(skip)]
-            factor: usize,
-        },
-        #[tabled(inline)]
-        Plain(#[tabled(rename = "password")] String),
-    }
-}
-
-mod __ {
-    #[test]
-    fn dont_import_the_trait() {
-        #[derive(tabled::Tabled)]
-        struct __;
-    }
-}
-
-test_table!(
-    test_display_type_0,
-    {
-        #[derive(Tabled)]
-        #[tabled(display(Password, "password_fmt"))]
-        struct User {
-            id: usize,
-            pass: Password,
-            mirrow: Password,
-        }
-
-        struct Password([u8; 4]);
-
-        fn password_fmt(p: &Password) -> String {
-            p.0.iter().sum::<u8>().to_string()
-        }
-
-        let data = [
-            User {
-                id: 0,
-                pass: Password([0, 1, 2, 3]),
-                mirrow: Password([1, 1, 1, 1]),
-            },
-            User {
-                id: 1,
-                pass: Password([1, 1, 2, 3]),
-                mirrow: Password([2, 2, 1, 1]),
-            },
-        ];
-
-        Table::new(data)
-    },
-    "+----+------+--------+"
-    "| id | pass | mirrow |"
-    "+----+------+--------+"
-    "| 0  | 6    | 4      |"
-    "+----+------+--------+"
-    "| 1  | 7    | 6      |"
-    "+----+------+--------+"
-);
-
-test_table!(
-    test_display_type_args,
-    {
-        #[derive(Tabled)]
-        #[tabled(display(Password, "password_fmt", self, 0))]
-        struct User {
-            id: usize,
-            pass: Password,
-            mirrow: Password,
-        }
-
-        struct Password([u8; 4]);
-
-        fn password_fmt(p: &Password, _: &User, _: usize) -> String {
-            p.0.iter().sum::<u8>().to_string()
-        }
-
-        let data = [
-            User {
-                id: 0,
-                pass: Password([0, 1, 2, 3]),
-                mirrow: Password([1, 1, 1, 1]),
-            },
-            User {
-                id: 1,
-                pass: Password([1, 1, 2, 3]),
-                mirrow: Password([2, 2, 1, 1]),
-            },
-        ];
-
-        Table::new(data)
-    },
-    "+----+------+--------+"
-    "| id | pass | mirrow |"
-    "+----+------+--------+"
-    "| 0  | 6    | 4      |"
-    "+----+------+--------+"
-    "| 1  | 7    | 6      |"
-    "+----+------+--------+"
-);
-
-test_table!(
-    test_display_type_generic,
-    {
-        #[derive(Tabled)]
-        #[tabled(display(Password, "password_fmt"))]
-        struct User {
-            id: usize,
-            pass: Password<usize>,
-            mirrow: Password<u8>,
-        }
-
-        struct Password<T>([T; 4]);
-
-        fn password_fmt<T>(p: &Password<T>) -> String where T: Display {
-            p.0.iter().map(|s| s.to_string()).collect::<Vec<_>>().join("-")
-        }
-
-        let data = [
-            User {
-                id: 0,
-                pass: Password([0, 1, 2, 3]),
-                mirrow: Password([1, 1, 1, 1]),
-            },
-            User {
-                id: 1,
-                pass: Password([1, 1, 2, 3]),
-                mirrow: Password([2, 2, 1, 1]),
-            },
-        ];
-
-        Table::new(data)
-    },
-    "+----+---------+---------+"
-    "| id | pass    | mirrow  |"
-    "+----+---------+---------+"
-    "| 0  | 0-1-2-3 | 1-1-1-1 |"
-    "+----+---------+---------+"
-    "| 1  | 1-1-2-3 | 2-2-1-1 |"
-    "+----+---------+---------+"
-);
-
-test_table!(
-    test_display_type_generic_use,
-    {
-        #[derive(Tabled)]
-        #[tabled(display(Password<usize>, "password_usize_fmt"))]
-        #[tabled(display(Password<u8>, "password_u8_fmt"))]
-        struct User {
-            id: usize,
-            pass: Password<usize>,
-            mirrow: Password<u8>,
-        }
-
-        struct Password<T>([T; 4]);
-
-        fn password_usize_fmt(p: &Password<usize>) -> String {
-            p.0.iter().sum::<usize>().to_string()
-        }
-
-        fn password_u8_fmt(p: &Password<u8>) -> String {
-            p.0.iter().sum::<u8>().to_string()
-        }
-
-        let data = [
-            User {
-                id: 0,
-                pass: Password([0, 1, 2, 3]),
-                mirrow: Password([1, 1, 1, 1]),
-            },
-            User {
-                id: 1,
-                pass: Password([1, 1, 2, 3]),
-                mirrow: Password([2, 2, 1, 1]),
-            },
-        ];
-
-        Table::new(data)
-    },
-    "+----+------+--------+"
-    "| id | pass | mirrow |"
-    "+----+------+--------+"
-    "| 0  | 6    | 4      |"
-    "+----+------+--------+"
-    "| 1  | 7    | 6      |"
-    "+----+------+--------+"
-);
-
-#[cfg(test)]
-mod test_display_enum {
-    use super::*;
-
-    #[derive(Tabled)]
-    pub enum User {
-        #[tabled(display("some::bar::user_fmt"))]
-        Public { id: usize },
-        #[tabled(display("user_fmt"))]
-        Private { id: usize },
-    }
-
-    fn user_fmt(_: &User) -> String {
-        format!("...")
-    }
-
-    pub mod some {
-        pub mod bar {
-            pub fn user_fmt(_: &super::super::User) -> String {
-                format!("111")
-            }
-        }
-    }
-
-    test_table!(
-        test_display_enum,
-        {
-            let data = [
-                User::Public { id: 0 },
-                User::Private { id: 1 },
-            ];
-
-            Table::new(data)
-        },
-        "+--------+---------+"
-        "| Public | Private |"
-        "+--------+---------+"
-        "| 111    |         |"
-        "+--------+---------+"
-        "|        | ...     |"
-        "+--------+---------+"
-    );
-}
-
-// TODO: Shall we support a 'display_type' for #inlined structs??
-// Seems like we have to?
-// But there's a small issue currently - we treat enum variants as field currently in a parsing stage.
-// And this particular case have no scense applied to struct field.
-// Soooo
-// Yes..
-//
-// test_table!(
-//     test_display_type_enum,
-//     {
-//         #[derive(Tabled)]
-//         enum User {
-//             #[tabled(inline)]
-//             #[tabled(display(Password<usize>, "password_usize_fmt"))]
-//             #[tabled(display(Password<u8>, "password_u8_fmt"))]
-//             Public {
-//                 id: usize,
-//                 pass: Password<usize>,
-//                 mirrow: Password<u8>,
-//             },
-//             #[tabled(display("user_fmt"))]
-//             Private {
-//                 id: usize,
-//             }
-//         }
-
-//         struct Password<T>([T; 4]);
-
-//         fn password_usize_fmt(p: &Password<usize>) -> String {
-//             p.0.iter().sum::<usize>().to_string()
-//         }
-
-//         fn password_u8_fmt(p: &Password<u8>) -> String {
-//             p.0.iter().sum::<u8>().to_string()
-//         }
-
-//         fn user_fmt(p: &User) -> String {
-//             format!("...")
-//         }
-
-//         let data = [
-//             User::Public {
-//                 id: 0,
-//                 pass: Password([0, 1, 2, 3]),
-//                 mirrow: Password([1, 1, 1, 1]),
-//             },
-//             User::Private {
-//                 id: 1,
-//             },
-//         ];
-
-//         Table::new(data)
-//     },
-//     "+----+------+--------+"
-//     "| id | pass | mirrow |"
-//     "+----+------+--------+"
-//     "| 0  | 6    | 4      |"
-//     "+----+------+--------+"
-//     "| 1  | 7    | 6      |"
-//     "+----+------+--------+"
-// );
diff --git a/tabled/tests/derive/display_test.rs b/tabled/tests/derive/display_test.rs
new file mode 100644
index 0000000..9ed55b4
--- /dev/null
+++ b/tabled/tests/derive/display_test.rs
@@ -0,0 +1,815 @@
+#![cfg(feature = "derive")]
+
+use std::fmt::Display;
+
+use tabled::{Table, Tabled};
+use testing_table::test_table;
+
+use super::{sstr, test_enum, test_struct, test_tuple};
+
+test_tuple!(
+    display_option,
+    declare: { { u8 #[tabled(display = "display_option")] Option<sstr> } }
+    init: {
+        fn display_option(o: &Option<sstr>) -> String {
+            match o {
+                Some(s) => format!("some {s}"),
+                None => "none".to_string(),
+            }
+        }
+    }
+    define: { 0 Some("v2") }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_tuple!(
+    display_option_args,
+    declare: { { u8 #[tabled(display("display_option", 1, "234"))] Option<sstr> } }
+    init: {
+        fn display_option(_opt: &Option<sstr>, val: usize, text: &str) -> String {
+            format!("some {val} {text}")
+        }
+    }
+    define: { 0 Some("v2") }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "some 1 234"] }
+);
+
+test_tuple!(
+    display_option_self,
+    declare: { { u8 #[tabled(display = "Self::display_option")] Option<sstr> } }
+    init: {
+        impl Test {
+            fn display_option(o: &Option<sstr>) -> String {
+                match o {
+                    Some(s) => format!("some {s}"),
+                    None => "none".to_string(),
+                }
+            }
+        }
+    }
+    define: { 0 Some("v2") }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_tuple!(
+    display_option_self_2,
+    declare: { { u8 #[tabled(display("Self::display_option", self))] Option<sstr> } }
+    init: {
+        impl Test {
+            fn display_option(_opt: &Option<sstr>, o: &Test) -> String {
+                match o.1 {
+                    Some(s) => format!("some {s}"),
+                    None => "none".to_string(),
+                }
+            }
+        }
+    }
+    define: { 0 Some("v2") }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_tuple!(
+    display_option_self_3,
+    declare: { { u8 #[tabled(display("display_option", self))] Option<sstr> } }
+    init: {
+        fn display_option(_opt: &Option<sstr>, o: &Test) -> String {
+            match o.1 {
+                Some(s) => format!("some {s}"),
+                None => "none".to_string(),
+            }
+        }
+    }
+    define: { 0 Some("v2") }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_tuple!(
+    display_option_self_4,
+    declare: { { u8 #[tabled(display("display_option", self.0, self.0))] Option<sstr> } }
+    init: {
+        fn display_option(_opt: &Option<sstr>, o1: u8, o2: u8) -> String {
+            format!("some {o1}.{o2}")
+        }
+    }
+    define: { 0 Some("v2") }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "some 0.0"] }
+);
+
+test_enum!(
+    enum_with_display,
+    declare: {
+        {
+            #[tabled(inline)]
+            A(
+                #[tabled(display = "format::<4>")]
+                sstr
+            )
+            B
+        }
+    }
+    init: {
+        fn format<const ID: usize>(_: sstr) -> String {
+            ID.to_string()
+        }
+    }
+    assert_headers: { ["0", "B"] }
+    assert: {
+        A("") => ["4", ""],
+        B => ["", "+"],
+    }
+);
+
+test_enum!(
+    enum_with_display_self,
+    declare: {
+        {
+            #[tabled(inline)]
+            A(
+                #[tabled(display("Self::format::<4>", self))]
+                sstr
+            )
+            B
+        }
+    }
+    init: {
+        impl Test {
+            fn format<const ID: usize>(_opt: &sstr, _: &Self) -> String {
+                ID.to_string()
+            }
+        }
+    }
+    assert_headers: { ["0", "B"] }
+    assert: {
+        A("") => ["4", ""],
+        B => ["", "+"],
+    }
+);
+
+test_enum!(
+    enum_with_display_self_complex_0,
+    declare: {
+        {
+            #[tabled(inline)]
+            A(
+                #[tabled(display("Self::format::<4>", self, self.0))]
+                sstr
+            )
+            B
+        }
+    }
+    init: {
+        impl Test {
+            fn format<const ID: usize>(_opt: &sstr, _: &Self, _: sstr) -> String {
+                ID.to_string()
+            }
+        }
+    }
+    assert_headers: { ["0", "B"] }
+    assert: {
+        A("") => ["4", ""],
+        B => ["", "+"],
+    }
+);
+
+test_enum!(
+    enum_with_display_self_complex_1,
+    declare: {
+        {
+            #[tabled(inline)]
+            A{
+                #[tabled(display("Self::format::<4>", self, self.asd))]
+                asd: sstr
+            }
+            B
+        }
+    }
+    init: {
+        impl Test {
+            fn format<const ID: usize>(_opt: &sstr, _: &Self, _: sstr) -> String {
+                ID.to_string()
+            }
+        }
+    }
+    assert_headers: { ["asd", "B"] }
+    assert: {
+        A { asd: "" } => ["4", ""],
+        B => ["", "+"],
+    }
+);
+
+test_enum!(
+    enum_display_with_variant,
+    declare: {
+        {
+            #[tabled(display = "display_variant1")]
+            AbsdEgh { a: u8, b: i32 }
+            #[tabled(display = "display_variant2::<200>")]
+            B(String)
+            K
+        }
+    }
+    init: {
+        fn display_variant1(_: &Test) -> &'static str {
+            "Hello World"
+        }
+
+        fn display_variant2<const VAL: usize>(_: &Test) -> String {
+            format!("asd {VAL}")
+        }
+    }
+    assert_headers: { ["AbsdEgh", "B", "K"] }
+    assert: {
+        AbsdEgh { a: 0, b: 0 }  => ["Hello World", "", ""],
+        B(String::new()) => ["", "asd 200", ""],
+        K => ["", "", "+"],
+    }
+);
+
+test_enum!(
+    enum_display_with_self_variant,
+    declare: {
+        {
+            #[tabled(display("display_variant1", self))]
+            AbsdEgh { a: u8, b: i32 }
+            #[tabled(display("display_variant2::<200, _>", self))]
+            B(String)
+            K
+        }
+    }
+    init: {
+        fn display_variant1<D>(_: &Test, _: &D) -> &'static str {
+            "Hello World"
+        }
+
+        fn display_variant2<const VAL: usize, D>(_: &Test, _: &D) -> String {
+            format!("asd {VAL}")
+        }
+    }
+    assert_headers: { ["AbsdEgh", "B", "K"] }
+    assert: {
+        AbsdEgh { a: 0, b: 0 }  => ["Hello World", "", ""],
+        B(String::new()) => ["", "asd 200", ""],
+        K => ["", "", "+"],
+    }
+);
+
+test_enum!(
+    enum_display_with_arguments,
+    declare: {
+        {
+            #[tabled(display("display1", 1, 2, self))]
+            AbsdEgh { a: u8, b: i32 }
+            #[tabled(display("display2::<200>", "Hello World"))]
+            B(String)
+            #[tabled(display("display1", 100, 200, self))]
+            K
+        }
+    }
+    init: {
+        fn display1<D>(_: &Test, val: usize, val2: usize, _: &D) -> String {
+            format!("{val} {val2}")
+        }
+
+        fn display2<const VAL: usize>(_: &Test, val: &str) -> String {
+            format!("asd {VAL} {val}")
+        }
+    }
+    assert_headers: { ["AbsdEgh", "B", "K"] }
+    assert: {
+        AbsdEgh { a: 0, b: 0 }  => ["1 2", "", ""],
+        B(String::new()) => ["", "asd 200 Hello World", ""],
+        K => ["", "", "100 200"],
+    }
+);
+
+test_struct!(
+    struct_display_with,
+    declare: {
+        {
+            f1: u8,
+            #[tabled(display = "display_option")]
+            f2: Option<sstr>,
+        }
+    }
+    init: {
+        fn display_option(o: &Option<sstr>) -> String {
+            match o {
+                Some(s) => format!("some {s}"),
+                None => "none".to_string(),
+            }
+        }
+    }
+    define: { f1: 0, f2: Some("v2") }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_struct!(
+    struct_display_with_args,
+    declare: {
+        {
+            f1: u8,
+            #[tabled(display("display_option", 1, 2, 3))]
+            f2: Option<sstr>,
+        }
+    }
+    init: {
+        fn display_option(_opt: &Option<sstr>, v1: usize, v2: usize, v3: usize) -> String {
+            format!("{v1} {v2} {v3}")
+        }
+    }
+    define: { f1: 0, f2: Some("v2") }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "1 2 3"] }
+);
+
+test_struct!(
+    struct_display_with_args_using_self,
+    declare: {
+        {
+            f1: u8,
+            #[tabled(display("display_option", &self.f1, 2, 3))]
+            f2: Option<sstr>,
+        }
+    }
+    init: {
+        fn display_option(_opt: &Option<sstr>, v1: &u8, v2: usize, v3: usize) -> String {
+            format!("{v1} {v2} {v3}")
+        }
+    }
+    define: { f1: 0, f2: Some("v2") }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "0 2 3"] }
+);
+
+test_struct!(
+    struct_display_with_self_static_method,
+    declare: {
+        {
+            f1: u8,
+            #[tabled(display = "Self::display_option")]
+            f2: Option<sstr>,
+        }
+    }
+    init: {
+        impl Test {
+            fn display_option(o: &Option<sstr>) -> String {
+                match o {
+                    Some(s) => format!("some {s}"),
+                    None => "none".to_string(),
+                }
+            }
+        }
+    }
+    define: { f1: 0, f2: Some("v2") }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_struct!(
+    struct_display_with_self_static_method_2,
+    declare: {
+        {
+            f1: u8,
+            #[tabled(display("Self::display_option", self))]
+            f2: Option<sstr>,
+        }
+    }
+    init: {
+        impl Test {
+            fn display_option(_opt: &Option<sstr>, o: &Test) -> String {
+                match o.f2 {
+                    Some(s) => format!("some {s}"),
+                    None => "none".to_string(),
+                }
+            }
+        }
+    }
+    define: { f1: 0, f2: Some("v2") }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_struct!(
+    struct_display_with_self_2_self_static_method_2,
+    declare: {
+        {
+            f1: u8,
+            #[tabled(display("Self::display_option", self))]
+            f2: Option<sstr>,
+        }
+    }
+    init: {
+        impl Test {
+            fn display_option(_opt: &Option<sstr>, s: &Self) -> String {
+                match s.f2 {
+                    Some(s) => format!("some {s}"),
+                    None => "none".to_string(),
+                }
+            }
+        }
+    }
+    define: { f1: 0, f2: Some("v2") }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_struct!(
+    struct_display_with_self_2_self_static_method,
+    declare: {
+        {
+            f1: u8,
+            #[tabled(display("display_option", self))]
+            f2: Option<sstr>,
+        }
+    }
+    init: {
+        fn display_option(_opt: &Option<sstr>, o: &Test) -> String {
+            match o.f2 {
+                Some(s) => format!("some {s}"),
+                None => "none".to_string(),
+            }
+        }
+    }
+    define: { f1: 0, f2: Some("v2") }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0", "some v2"] }
+);
+
+test_struct!(
+    struct_display_with_args_using_self_array_and_func,
+    declare: {
+        {
+            #[tabled(skip)]
+            f1: [u8; 4],
+            #[tabled(display("display_option", &[self.f1[0], self.f1[1]], ToString::to_string(&self.f3.to_string())))]
+            f2: Option<sstr>,
+            f3: usize,
+        }
+    }
+    init: {
+        fn display_option(_opt: &Option<sstr>, v1: &[u8; 2], v4: String) -> String {
+            format!("{} {} {v4}", v1[0], v1[1])
+        }
+    }
+    define: { f1: [0, 1, 2, 3], f2: Some("v2"), f3: 100 }
+    assert_headers: { ["f2", "f3"] }
+    assert_fields: { ["0 1 100", "100"] }
+);
+
+#[test]
+#[allow(dead_code)]
+fn test_macros_in_display_with() {
+    #[derive(Tabled)]
+    #[tabled(rename_all = "camelCase")]
+    struct Country {
+        name: String,
+        #[tabled(display("display_capital", format!(".{}", self.capital)))]
+        capital: String,
+        #[tabled(display("display_perimeter", self))]
+        area_km2: f32,
+        #[tabled(display = "str::to_lowercase")]
+        national_currency: String,
+        national_currency_short: String,
+    }
+
+    fn display_perimeter(_area: &f32, country: &Country) -> sstr {
+        if country.area_km2 > 1_000_000.0 {
+            "Very Big Land"
+        } else {
+            "Big Land"
+        }
+    }
+
+    fn display_capital(_capital: &str, country: String) -> std::borrow::Cow<'static, str> {
+        format!("{country}!").into()
+    }
+}
+
+#[cfg(test)]
+mod test_display_enum {
+    use super::*;
+
+    #[derive(Tabled)]
+    pub enum User {
+        #[tabled(display("some::bar::user_fmt"))]
+        Public { id: usize },
+        #[tabled(display("user_fmt"))]
+        Private { id: usize },
+    }
+
+    fn user_fmt(_: &User) -> String {
+        format!("...")
+    }
+
+    pub mod some {
+        pub mod bar {
+            pub fn user_fmt(_: &super::super::User) -> String {
+                format!("111")
+            }
+        }
+    }
+
+    test_table!(
+        test_display_enum,
+        {
+            let data = [
+                User::Public { id: 0 },
+                User::Private { id: 1 },
+            ];
+
+            Table::new(data)
+        },
+        "+--------+---------+"
+        "| Public | Private |"
+        "+--------+---------+"
+        "| 111    |         |"
+        "+--------+---------+"
+        "|        | ...     |"
+        "+--------+---------+"
+    );
+}
+
+test_table!(
+    test_display_type_0,
+    {
+        #[derive(Tabled)]
+        #[tabled(display(Password, "password_fmt"))]
+        struct User {
+            id: usize,
+            pass: Password,
+            mirrow: Password,
+        }
+
+        struct Password([u8; 4]);
+
+        fn password_fmt(p: &Password) -> String {
+            p.0.iter().sum::<u8>().to_string()
+        }
+
+        let data = [
+            User { id: 0, pass: Password([0, 1, 2, 3]), mirrow: Password([1, 1, 1, 1]) },
+            User { id: 1, pass: Password([1, 1, 2, 3]), mirrow: Password([2, 2, 1, 1]) },
+        ];
+
+        Table::new(data)
+    },
+    "+----+------+--------+"
+    "| id | pass | mirrow |"
+    "+----+------+--------+"
+    "| 0  | 6    | 4      |"
+    "+----+------+--------+"
+    "| 1  | 7    | 6      |"
+    "+----+------+--------+"
+);
+
+test_table!(
+    test_display_type_args,
+    {
+        #[derive(Tabled)]
+        #[tabled(display(Password, "password_fmt", self, 0))]
+        struct User {
+            id: usize,
+            pass: Password,
+            mirrow: Password,
+        }
+
+        struct Password([u8; 4]);
+
+        fn password_fmt(p: &Password, _: &User, _: usize) -> String {
+            p.0.iter().sum::<u8>().to_string()
+        }
+
+        let data = [
+            User {
+                id: 0,
+                pass: Password([0, 1, 2, 3]),
+                mirrow: Password([1, 1, 1, 1]),
+            },
+            User {
+                id: 1,
+                pass: Password([1, 1, 2, 3]),
+                mirrow: Password([2, 2, 1, 1]),
+            },
+        ];
+
+        Table::new(data)
+    },
+    "+----+------+--------+"
+    "| id | pass | mirrow |"
+    "+----+------+--------+"
+    "| 0  | 6    | 4      |"
+    "+----+------+--------+"
+    "| 1  | 7    | 6      |"
+    "+----+------+--------+"
+);
+
+test_table!(
+    test_display_type_generic,
+    {
+        #[derive(Tabled)]
+        #[tabled(display(Password, "password_fmt"))]
+        struct User {
+            id: usize,
+            pass: Password<usize>,
+            mirrow: Password<u8>,
+        }
+
+        struct Password<T>([T; 4]);
+
+        fn password_fmt<T>(p: &Password<T>) -> String where T: Display {
+            p.0.iter().map(|s| s.to_string()).collect::<Vec<_>>().join("-")
+        }
+
+        let data = [
+            User {
+                id: 0,
+                pass: Password([0, 1, 2, 3]),
+                mirrow: Password([1, 1, 1, 1]),
+            },
+            User {
+                id: 1,
+                pass: Password([1, 1, 2, 3]),
+                mirrow: Password([2, 2, 1, 1]),
+            },
+        ];
+
+        Table::new(data)
+    },
+    "+----+---------+---------+"
+    "| id | pass    | mirrow  |"
+    "+----+---------+---------+"
+    "| 0  | 0-1-2-3 | 1-1-1-1 |"
+    "+----+---------+---------+"
+    "| 1  | 1-1-2-3 | 2-2-1-1 |"
+    "+----+---------+---------+"
+);
+
+test_table!(
+    test_display_type_generic_use,
+    {
+        #[derive(Tabled)]
+        #[tabled(display(Password<usize>, "password_usize_fmt"))]
+        #[tabled(display(Password<u8>, "password_u8_fmt"))]
+        struct User {
+            id: usize,
+            pass: Password<usize>,
+            mirrow: Password<u8>,
+        }
+
+        struct Password<T>([T; 4]);
+
+        fn password_usize_fmt(p: &Password<usize>) -> String {
+            p.0.iter().sum::<usize>().to_string()
+        }
+
+        fn password_u8_fmt(p: &Password<u8>) -> String {
+            p.0.iter().sum::<u8>().to_string()
+        }
+
+        let data = [
+            User {
+                id: 0,
+                pass: Password([0, 1, 2, 3]),
+                mirrow: Password([1, 1, 1, 1]),
+            },
+            User {
+                id: 1,
+                pass: Password([1, 1, 2, 3]),
+                mirrow: Password([2, 2, 1, 1]),
+            },
+        ];
+
+        Table::new(data)
+    },
+    "+----+------+--------+"
+    "| id | pass | mirrow |"
+    "+----+------+--------+"
+    "| 0  | 6    | 4      |"
+    "+----+------+--------+"
+    "| 1  | 7    | 6      |"
+    "+----+------+--------+"
+);
+
+test_struct!(
+    display_with_and_rename,
+    declare: {
+        {
+            f1: sstr,
+            f2: sstr,
+            #[tabled(display = "print", rename = "asd")]
+            f3: usize,
+        }
+    }
+    init: {
+        fn print<T>(_: T) -> String { String::new() }
+    }
+    define: { f1: "123", f2: "456", f3: 789 }
+    assert_headers: { ["f1", "f2", "asd"] }
+    assert_fields: { ["123", "456", ""] }
+);
+
+test_struct!(
+    display_with_and_rename_2,
+    declare: {
+        {
+            f1: sstr,
+            f2: sstr,
+            #[tabled(display = "print")]
+            #[tabled(rename = "asd")]
+            f3: usize,
+        }
+    }
+    init: {
+        fn print<T>(_: T) -> String { String::new() }
+    }
+    define: { f1: "123", f2: "456", f3: 789 }
+    assert_headers: { ["f1", "f2", "asd"] }
+    assert_fields: { ["123", "456", ""] }
+);
+
+test_struct!(
+    display_with_and_rename_all,
+    declare: {
+        {
+            f1: sstr,
+            f2: sstr,
+            #[tabled(display = "print", rename_all = "UPPERCASE")]
+            f3: usize,
+        }
+    }
+    init: {
+        fn print<T>(_: T) -> String { String::new() }
+    }
+    define: { f1: "123", f2: "456", f3: 789 }
+    assert_headers: { ["f1", "f2", "F3"] }
+    assert_fields: { ["123", "456", ""] }
+);
+
+// TODO: Shall we support a 'display_type' for #inlined structs??
+// Seems like we have to?
+// But there's a small issue currently - we treat enum variants as field currently in a parsing stage.
+// And this particular case have no scense applied to struct field.
+// Soooo
+// Yes..
+//
+// test_table!(
+//     test_display_type_enum,
+//     {
+//         #[derive(Tabled)]
+//         enum User {
+//             #[tabled(inline)]
+//             #[tabled(display(Password<usize>, "password_usize_fmt"))]
+//             #[tabled(display(Password<u8>, "password_u8_fmt"))]
+//             Public {
+//                 id: usize,
+//                 pass: Password<usize>,
+//                 mirrow: Password<u8>,
+//             },
+//             #[tabled(display("user_fmt"))]
+//             Private {
+//                 id: usize,
+//             }
+//         }
+
+//         struct Password<T>([T; 4]);
+
+//         fn password_usize_fmt(p: &Password<usize>) -> String {
+//             p.0.iter().sum::<usize>().to_string()
+//         }
+
+//         fn password_u8_fmt(p: &Password<u8>) -> String {
+//             p.0.iter().sum::<u8>().to_string()
+//         }
+
+//         fn user_fmt(p: &User) -> String {
+//             format!("...")
+//         }
+
+//         let data = [
+//             User::Public {
+//                 id: 0,
+//                 pass: Password([0, 1, 2, 3]),
+//                 mirrow: Password([1, 1, 1, 1]),
+//             },
+//             User::Private {
+//                 id: 1,
+//             },
+//         ];
+
+//         Table::new(data)
+//     },
+//     "+----+------+--------+"
+//     "| id | pass | mirrow |"
+//     "+----+------+--------+"
+//     "| 0  | 6    | 4      |"
+//     "+----+------+--------+"
+//     "| 1  | 7    | 6      |"
+//     "+----+------+--------+"
+// );
diff --git a/tabled/tests/derive/format_test.rs b/tabled/tests/derive/format_test.rs
new file mode 100644
index 0000000..a71b0ff
--- /dev/null
+++ b/tabled/tests/derive/format_test.rs
@@ -0,0 +1,183 @@
+#![cfg(feature = "derive")]
+
+use tabled::Tabled;
+
+use super::{sstr, test_enum, test_struct, test_tuple};
+
+test_tuple!(
+    tuple_format_1,
+    declare: { { u8 #[tabled(format = "foo {}")] sstr } }
+    init: {}
+    define: { 0 "v2" }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "foo v2"] }
+);
+
+test_tuple!(
+    tuple_format_2,
+    declare: { { u8 #[tabled(format = "foo {:?}")] sstr } }
+    init: {}
+    define: { 0 "v2" }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "foo \"v2\""] }
+);
+
+// todo : self represents the tuple here. It should be the sstr element instead.
+test_tuple!(
+    tuple_format_3,
+    declare: {
+        #[allow(dead_code)]
+        #[derive(Debug)]
+        {
+            u8
+            #[tabled(format("foo {} {:?}", 2, self))]
+            String
+        }
+    }
+    init: {}
+    define: { 0 String::from("string") }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "foo 2 Test(0, \"string\")"] }
+);
+
+test_enum!(
+    enum_format,
+    declare: {
+        {
+            #[tabled(inline)]
+            AbsdEgh {
+                #[tabled(format("{}-{}", self.a, self.b))]
+                a: u8,
+                b: i32
+            }
+            #[tabled(format("{} s", 4))]
+            B(String)
+            #[tabled(inline)]
+            C(
+                #[tabled(rename = "C", format("{} ss", 4))]
+                String
+            )
+            #[tabled(format = "k.")]
+            K
+        }
+    }
+    init: {}
+    assert_headers: { ["a", "b", "B", "C", "K"] }
+    assert: {
+        AbsdEgh { a: 0, b: 1 }  => ["0-1", "1", "", "", ""],
+        B(String::new()) => ["",  "", "4 s", "", ""],
+        C(String::new()) => ["", "",  "", "4 ss", ""],
+        K => ["", "", "",  "", "k."],
+    }
+);
+
+test_enum!(
+    enum_format_complex,
+    declare: {
+        {
+            #[tabled(inline)]
+            AbsdEgh {
+                #[tabled(format("{}-{}-{}", foo(*self.a as usize), foo(*self.b as usize), self.c[2]))]
+                a: u8,
+                b: i32,
+                #[tabled(skip)]
+                c: Vec<usize>,
+            }
+            #[tabled(format("{} s", foo(4)))]
+            B(String)
+            #[tabled(inline)]
+            C(
+                #[tabled(rename = "C", format("{} ss {}", foo(4), self.1[2]))]
+                String,
+                #[tabled(skip)]
+                Vec<usize>,
+            )
+            #[tabled(format = "k.")]
+            K
+        }
+    }
+    init: {
+        fn foo(a: usize) -> String {
+            if a > 100 {
+                String::from(">100")
+            } else {
+                String::from("<100")
+            }
+        }
+    }
+    assert_headers: { ["a", "b", "B", "C", "K"] }
+    assert: {
+        AbsdEgh { a: 0, b: 1, c: vec![1, 2, 3] }  => ["<100-<100-3", "1", "", "", ""],
+        B(String::new()) => ["",  "", "<100 s", "", ""],
+        C(String::new(), vec![1, 2, 3]) => ["", "",  "", "<100 ss 3", ""],
+        K => ["", "", "",  "", "k."],
+    }
+);
+
+test_struct!(
+    struct_format,
+    declare: {
+        {
+            #[tabled(format = "{} cc")]
+            f1: u8,
+            f2: u8,
+        }
+    }
+    init: {}
+    define: { f1: 0, f2: 0 }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["0 cc", "0"] }
+);
+
+test_struct!(
+    struct_format_with_args,
+    declare: {
+        {
+            #[tabled(format("{}/{} cc/kg", self.f1, self.f2))]
+            f1: u8,
+            f2: u8,
+        }
+    }
+    init: {}
+    define: { f1: 1, f2: 2 }
+    assert_headers: { ["f1", "f2"] }
+    assert_fields: { ["1/2 cc/kg", "2"] }
+);
+
+#[test]
+#[allow(dead_code)]
+fn test_macros_in_format() {
+    #[derive(Tabled)]
+    struct Country {
+        name: String,
+        #[tabled(format("{}", format!(".{}", self.capital)))]
+        capital: String,
+        #[tabled(format("{}", self.field1[0]))]
+        field1: [u8; 4],
+    }
+}
+
+#[test]
+#[allow(dead_code)]
+fn test_enum_format_1() {
+    #[derive(Tabled)]
+    struct User {
+        #[tabled(format("{}.{}.{}.{}", self.ip[0], self.ip[1], self.ip[2], self.ip[3]))]
+        ip: [u8; 4],
+        #[tabled(inline)]
+        password: Password,
+    }
+
+    #[derive(Tabled)]
+    enum Password {
+        #[tabled(inline)]
+        Mask {
+            #[tabled(format("t={}/{}", self.text, self.factor))]
+            text: String,
+            #[tabled(skip)]
+            factor: usize,
+        },
+        #[tabled(inline)]
+        Plain(#[tabled(rename = "password")] String),
+    }
+}
diff --git a/tabled/tests/derive/inline_test.rs b/tabled/tests/derive/inline_test.rs
new file mode 100644
index 0000000..aafd02b
--- /dev/null
+++ b/tabled/tests/derive/inline_test.rs
@@ -0,0 +1,510 @@
+#![cfg(feature = "derive")]
+
+use tabled::Tabled;
+
+use super::{sstr, test_enum, test_struct};
+
+test_enum!(
+    inline_enum_as_whole_and_rename,
+    declare: {
+        #[tabled(inline, rename_all = "snake_case")]
+        {
+            AbsdEgh { a: u8, b: i32 }
+            B(String)
+            K
+        }
+    }
+    init: {}
+    assert_headers: { ["Test"] }
+    assert: {
+        AbsdEgh { a: 0, b: 0 }  => ["absd_egh"],
+        B(String::new()) => ["b"],
+        K => ["k"],
+    }
+);
+
+test_enum!(
+    inline_enum_as_whole_and_rename_inner,
+    declare: {
+        #[tabled(inline)]
+        {
+            #[tabled(rename_all = "snake_case")]
+            AbsdEgh { a: u8, b: i32 }
+            #[tabled(rename_all = "lowercase")]
+            B(String)
+            K
+        }
+    }
+    init: {}
+    assert_headers: { ["Test"] }
+    assert: {
+        AbsdEgh { a: 0, b: 0 }  => ["absd_egh"],
+        B(String::new()) => ["b"],
+        K => ["K"],
+    }
+);
+
+test_enum!(
+    inline_variant,
+    declare: {
+        {
+            #[tabled(inline("Auto::"))]
+            Auto {
+                #[tabled(rename = "mod")]
+                model: sstr,
+                engine: sstr
+            }
+            #[tabled(inline)]
+            Bikecycle(
+                #[tabled(rename = "name")]
+                sstr,
+                #[tabled(inline)]
+                Bike
+            )
+            Skateboard
+        }
+    }
+    init: {
+        #[derive(Tabled)]
+        struct Bike { brand: sstr, price: f32 }
+    }
+    assert_headers: { ["Auto::mod", "Auto::engine", "name", "brand", "price", "Skateboard"] }
+    assert: {
+        Skateboard => ["", "", "", "", "", "+"],
+        Auto { model: "Mini", engine: "v8" } => ["Mini", "v8", "", "", "", ""],
+        Bikecycle("A bike", Bike { brand: "Canyon", price: 2000.0 })=> ["", "", "A bike", "Canyon", "2000", ""],
+    }
+);
+
+test_enum!(
+    enum_inline_field_with_display_function,
+    declare: {
+        {
+            #[tabled(inline("backend::"))]
+            Backend {
+                #[tabled(display = "display", rename = "name")]
+                value: sstr
+            }
+            Frontend
+        }
+    }
+    init: {
+        fn display(_: sstr) -> String {
+            "asd".to_string()
+        }
+    }
+    assert_headers: { ["backend::name", "Frontend"] }
+    assert: {
+        Backend { value: "123" } => ["asd", ""],
+        Frontend => ["", "+"],
+    }
+);
+
+test_enum!(
+    enum_inline_field_with_display_self_function,
+    declare: {
+        {
+            #[tabled(inline("backend::"))]
+            Backend {
+                #[tabled()]
+                #[tabled(display("display", self), rename = "name")]
+                value: sstr
+            }
+            Frontend
+        }
+    }
+    init: {
+        fn display<T>(_opt: &sstr, _: &T) -> String {
+            "asd".to_string()
+        }
+    }
+    assert_headers: { ["backend::name", "Frontend"] }
+    assert: {
+        Backend { value: "123" } => ["asd", ""],
+        Frontend => ["", "+"],
+    }
+);
+
+test_enum!(
+    rename_all_enum_inherited_inside_struct_enum,
+    declare: {
+        #[tabled(rename_all = "snake_case")]
+        {
+            #[tabled(inline)]
+            VariantName1 { some_field_1: u8, some_field_2: i32 }
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["some_field_1", "some_field_2", "variant_name2", "variant_name3"] }
+    assert: {
+        VariantName1 { some_field_1: 0, some_field_2: -1 } => ["0", "-1", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "", "+", ""],
+        VariantName3 => ["", "", "", "+"],
+    }
+);
+
+test_enum!(
+    rename_all_enum_inherited_inside_struct_override_by_rename_enum,
+    declare: {
+        #[tabled(rename_all = "snake_case")]
+        {
+            #[tabled(inline)]
+            VariantName1 {
+                #[tabled(rename = "f1")]
+                some_field_1: u8,
+                #[tabled(rename = "f2")]
+                some_field_2: i32,
+            }
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["f1", "f2", "variant_name2", "variant_name3"] }
+    assert: {
+        VariantName1 { some_field_1: 0, some_field_2: -1 } => ["0", "-1", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "", "+", ""],
+        VariantName3 => ["", "", "", "+"],
+    }
+);
+
+test_enum!(
+    rename_all_enum_inherited_inside_struct_override_by_rename_all_enum,
+    declare: {
+        #[tabled(rename_all = "snake_case")]
+        {
+            #[tabled(inline)]
+            VariantName1 {
+                #[tabled(rename_all = "UPPERCASE")]
+                some_field_1: u8,
+                #[tabled(rename_all = "CamelCase")]
+                some_field_2: i32,
+            }
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["SOMEFIELD1", "someField2", "variant_name2", "variant_name3"] }
+    assert: {
+        VariantName1 { some_field_1: 0, some_field_2: -1 } => ["0", "-1", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "", "+", ""],
+        VariantName3 => ["", "", "", "+"],
+    }
+);
+
+test_enum!(
+    rename_all_variant_inherited_inside_struct_enum,
+    declare: {
+        #[tabled(rename_all = "snake_case")]
+        {
+            #[tabled(inline)]
+            #[tabled(rename_all = "snake_case")]
+            VariantName1 {
+                some_field_1: u8,
+                some_field_2: i32,
+            }
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["some_field_1", "some_field_2", "variant_name2", "variant_name3"] }
+    assert: {
+        VariantName1 { some_field_1: 0, some_field_2: -1 } => ["0", "-1", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "", "+", ""],
+        VariantName3 => ["", "", "", "+"],
+    }
+);
+
+test_enum!(
+    rename_all_variant_inherited_inside_struct_enum_overridden_by_rename,
+    declare: {
+        #[tabled(rename_all = "snake_case")]
+        {
+            #[tabled(inline, rename_all = "snake_case")]
+            VariantName1 {
+                #[tabled(rename = "f1")]
+                some_field_1: u8,
+                #[tabled(rename = "f2")]
+                some_field_2: i32,
+            }
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["f1", "f2", "variant_name2", "variant_name3"] }
+    assert: {
+        VariantName1 { some_field_1: 0, some_field_2: -1 } => ["0", "-1", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "", "+", ""],
+        VariantName3 => ["", "", "", "+"],
+    }
+);
+
+test_enum!(
+    rename_all_variant_inherited_inside_struct_override_by_rename_all_enum,
+    declare: {
+        #[tabled(rename_all = "snake_case")]
+        {
+            #[tabled(rename_all = "snake_case", inline)]
+            VariantName1 {
+                #[tabled(rename_all = "UPPERCASE")]
+                some_field_1: u8,
+                #[tabled(rename_all = "CamelCase")]
+                some_field_2: i32,
+            }
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["SOMEFIELD1", "someField2", "variant_name2", "variant_name3"] }
+    assert: {
+        VariantName1 { some_field_1: 0, some_field_2: -1 } => ["0", "-1", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "", "+", ""],
+        VariantName3 => ["", "", "", "+"],
+    }
+);
+
+test_enum!(
+    inline_field_with_display_function,
+    declare: {
+        {
+            #[tabled(inline("backend::"))]
+            Backend {
+                #[tabled(display = "display", rename = "name")]
+                value: sstr
+            }
+            Frontend
+        }
+    }
+    init: {
+        fn display(_: sstr) -> String {
+            "asd".to_string()
+        }
+    }
+    assert_headers: { ["backend::name", "Frontend"] }
+    assert: {
+        Backend { value: "123" } => ["asd", ""],
+        Frontend => ["", "+"],
+    }
+);
+
+test_enum!(
+    inline_field_with_display_self_function,
+    declare: {
+        {
+            #[tabled(inline("backend::"))]
+            Backend {
+                #[tabled()]
+                #[tabled(display("display", self), rename = "name")]
+                value: sstr
+            }
+            Frontend
+        }
+    }
+    init: {
+        fn display<T>(_opt: &sstr, _: &T) -> String {
+            "asd".to_string()
+        }
+    }
+    assert_headers: { ["backend::name", "Frontend"] }
+    assert: {
+        Backend { value: "123" } => ["asd", ""],
+        Frontend => ["", "+"],
+    }
+);
+
+test_struct!(
+    ignore_display_with_when_used_with_inline,
+    declare: {
+        {
+            f1: sstr,
+            f2: sstr,
+            #[tabled(display = "print", inline)]
+            f3: usize,
+        }
+    }
+    init: {}
+    define: { f1: "123", f2: "456", f3: 789 }
+    assert_headers: { ["f1", "f2", "usize"] }
+    assert_fields: { ["123", "456", "789"] }
+);
+
+test_struct!(
+    ignore_display_with_when_used_with_inline_2,
+    declare: {
+        {
+            f1: sstr,
+            f2: sstr,
+            #[tabled(display = "print", )]
+            #[tabled(inline)]
+            f3: usize,
+        }
+    }
+    init: {}
+    define: { f1: "123", f2: "456", f3: 789 }
+    assert_headers: { ["f1", "f2", "usize"] }
+    assert_fields: { ["123", "456", "789"] }
+);
+
+test_struct!(
+    struct_inline,
+    declare: {
+        {
+            #[tabled(inline = true)]
+            id: u8,
+            name: sstr,
+            #[tabled(inline)]
+            ed: Education
+        }
+    }
+    init: {
+        #[derive(Tabled)]
+        struct Education { uni: sstr, graduated: bool }
+    }
+    define: {
+        id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }
+    }
+    assert_headers: { ["u8", "name","uni","graduated"] }
+    assert_fields: { ["0", "Maxim", "BNTU", "true"] }
+);
+
+test_struct!(
+    struct_inline_with_prefix,
+    declare: {
+        {
+            #[tabled(rename = "it's an ignored option", inline)]
+            id: u8,
+            name: sstr,
+            #[tabled(inline("education::"))]
+            ed: Education,
+        }
+    }
+    init: {
+        #[derive(Tabled)]
+        struct Education { uni: sstr, graduated: bool }
+    }
+    define: {
+        id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }}
+    assert_headers: { ["u8", "name","education::uni","education::graduated"] }
+    assert_fields: { ["0", "Maxim", "BNTU", "true"] }
+);
+
+test_enum!(
+    struct_skipped_fields_not_implement_display_enum,
+    declare: {
+        {
+            #[tabled(inline("A::"))]
+            A {
+                name: sstr
+            }
+            #[tabled(inline("B::"))]
+            B {
+                issue: usize,
+                name: sstr,
+                #[tabled(skip)]
+                _gem: (),
+            }
+            #[tabled(inline("C::"))]
+            C(usize, #[tabled(skip)] (), sstr)
+            D
+        }
+    }
+    init: {}
+    assert_headers: { ["A::name", "B::issue", "B::name", "C::0", "C::2", "D"] }
+    assert: {
+        A { name: "nrdxp" } => ["nrdxp", "", "", "", "", ""],
+        B { _gem: (), issue: 32, name: "nrdxp" } => ["", "32", "nrdxp", "", "", ""],
+        C(32, (), "nrdxp") => ["", "", "", "32", "nrdxp", ""],
+        D => ["", "", "", "", "", "+"],
+    }
+);
+
+test_enum!(
+    inline_enum_as_whole,
+    declare: {
+        #[tabled(inline)] {
+            AbsdEgh { a: u8, b: i32 }
+            B(String)
+            K
+        }
+    }
+    init: {}
+    assert_headers: { ["Test"] }
+    assert: {
+        AbsdEgh { a: 0, b: 0 }  => ["AbsdEgh"],
+        B(String::new()) => ["B"],
+        K => ["K"],
+    }
+);
+
+test_enum!(
+    inline_enum_name,
+    declare: {
+        #[tabled(inline("A struct name"))]
+        {
+            AbsdEgh { a: u8, b: i32 }
+            B(String)
+            K
+        }
+    }
+    init: {}
+    assert_headers: { ["A struct name"] }
+    assert: {
+        AbsdEgh { a: 0, b: 0 }  => ["AbsdEgh"],
+        B(String::new()) => ["B"],
+        K => ["K"],
+    }
+);
+
+test_enum!(
+    enum_order_0_inlined,
+    declare: {
+        #[tabled(inline)]
+        {
+            #[tabled(order = 1)]
+            V1(u8)
+            V2(u8)
+            V3(u8)
+        }
+    }
+    init: {}
+    assert_headers: { ["Test"] }
+    assert: {
+        V1(0) => ["V1"],
+        V2(0) => ["V2"],
+        V3(0) => ["V3"],
+    }
+);
+
+#[test]
+fn test_format_enum_inline() {
+    #[derive(Tabled)]
+    enum Struct {
+        #[tabled(inline)]
+        Variant1 {
+            #[tabled(rename = "cccc")]
+            #[tabled(format("{} {}", self.character, self.lang))]
+            character: char,
+            lang: u8,
+        },
+        Variant2(char),
+        Variant3,
+    }
+
+    assert_eq!(Struct::headers(), ["cccc", "lang", "Variant2", "Variant3"]);
+    assert_eq!(
+        Struct::Variant1 {
+            character: 'c',
+            lang: b'c'
+        }
+        .fields(),
+        ["c 99", "99", "", ""]
+    );
+    assert_eq!(Struct::Variant2('c').fields(), ["", "", "+", ""]);
+    assert_eq!(Struct::Variant3.fields(), ["", "", "", "+"]);
+}
diff --git a/tabled/tests/derive/map_test.rs b/tabled/tests/derive/map_test.rs
new file mode 100644
index 0000000..2db235d
--- /dev/null
+++ b/tabled/tests/derive/map_test.rs
@@ -0,0 +1,77 @@
+#![cfg(feature = "derive")]
+
+use tabled::{Table, Tabled};
+use testing_table::test_table;
+
+test_table!(
+    test_map_path,
+    {
+        #[derive(Tabled)]
+        struct User {
+            id: usize,
+            #[tabled(map = "password_string")]
+            p: Pass<usize>,
+        }
+
+        struct Pass<T>([T; 4]);
+
+        fn password_string(p: &Pass<usize>) -> String {
+            p.0.iter().sum::<usize>().to_string()
+        }
+
+        let data = [
+            User { id: 0, p: Pass([0, 1, 2, 3]) },
+            User { id: 1, p: Pass([1, 1, 2, 3]) },
+        ];
+
+        Table::new(data)
+    },
+    "+----+---+"
+    "| id | p |"
+    "+----+---+"
+    "| 0  | 6 |"
+    "+----+---+"
+    "| 1  | 7 |"
+    "+----+---+"
+);
+
+test_table!(
+    test_map_inline,
+    {
+        #[derive(Tabled)]
+        struct User {
+            id: usize,
+            #[tabled(map(Pass, "pass"))]
+            #[tabled(inline)]
+            p: isize,
+        }
+
+        #[derive(Tabled)]
+        struct Pass(String, String, String);
+
+        fn pass(p: &isize) -> Pass {
+            Pass (
+                (*p > 0).then_some(String::from("+")).unwrap_or_default(),
+                (*p < 0).then_some(String::from("-")).unwrap_or_default(),
+                (*p == 0).then_some(String::from("=")).unwrap_or_default(),
+            )
+        }
+
+        let data = [
+            User { id: 0, p: 0 },
+            User { id: 1, p: 1 },
+            User { id: 1, p: -1 },
+        ];
+
+        Table::new(data)
+    },
+    "+----+---+---+---+"
+    "| id | 0 | 1 | 2 |"
+    "+----+---+---+---+"
+    "| 0  |   |   | = |"
+    "+----+---+---+---+"
+    "| 1  | + |   |   |"
+    "+----+---+---+---+"
+    "| 1  |   | - |   |"
+    "+----+---+---+---+"
+);
diff --git a/tabled/tests/derive/mod.rs b/tabled/tests/derive/mod.rs
index d0d4b35..9ed4dc7 100644
--- a/tabled/tests/derive/mod.rs
+++ b/tabled/tests/derive/mod.rs
@@ -1,1 +1,175 @@
 mod derive_test;
+mod display_test;
+mod format_test;
+mod inline_test;
+mod map_test;
+mod order_test;
+mod rename_all_test;
+mod rename_test;
+mod skip_test;
+
+// https://users.rust-lang.org/t/create-a-struct-from-macro-rules/19829
+#[allow(unused_macros)]
+macro_rules! test_tuple {
+    (
+        $test_name:ident,
+        declare: {
+            $(#[$struct_attr:meta])*
+            { $( $(#[$attr:meta])* $ty:ty)* }
+        }
+        init: {
+            $($init_block:stmt)*
+        }
+        define: {
+            $($init:expr)*
+        }
+        assert_headers: { $headers:expr }
+        assert_fields: { $fields:expr }
+    ) => {
+
+        #[test]
+        fn $test_name() {
+            $($init_block)*
+
+            #[derive(Tabled)]
+            $(#[$struct_attr])*
+            struct Test(
+                $( $(#[$attr])* $ty, )*
+            );
+
+            let value = Test($($init,)*);
+
+            let fields: Vec<&'static str> = $fields.to_vec();
+            let headers: Vec<&'static str> = $headers.to_vec();
+
+            assert_eq!(value.fields(), fields);
+            assert_eq!(Test::headers(), headers);
+            assert_eq!(<Test as Tabled>::LENGTH, headers.len());
+            assert_eq!(<Test as Tabled>::LENGTH, fields.len());
+        }
+
+    };
+}
+
+#[allow(unused_macros)]
+macro_rules! test_enum {
+    (
+        $test_name:ident,
+        declare: {
+            $(#[$struct_attr:meta])*
+            {
+                $(
+                    $(#[$var_attr:meta])*
+                    $var:ident
+                    $({
+                        $( $(#[$attr:meta])* $field:ident: $ty:ty),* $(,)?
+                    })?
+                    $((
+                        $( $(#[$attr2:meta])* $ty2:ty),* $(,)?
+                    ))?
+                )*
+            }
+        }
+        init: {
+            $($init_block:stmt)*
+        }
+        assert_headers: {
+            $headers:expr
+        }
+        assert: {
+            $($init:expr => $expected:expr,)*
+        }
+    ) => {
+
+        #[test]
+        fn $test_name() {
+            $($init_block)*
+
+            #[derive(Tabled)]
+            $(#[$struct_attr])*
+            enum Test {
+                $(
+                    $(#[$var_attr])*
+                    $var $({
+                        $( $(#[$attr])* $field: $ty,)*
+                    })?
+
+                    $((
+                        $( $(#[$attr2])* $ty2,)*
+                    ))?
+                ),*
+            }
+
+            let headers: Vec<&'static str> = $headers.to_vec();
+            assert_eq!(Test::headers(), headers);
+            assert_eq!(<Test as Tabled>::LENGTH, headers.len());
+
+            {
+                use Test::*;
+                $(
+                    let variant = $init;
+                    let fields: Vec<&'static str> = $expected.to_vec();
+                    assert_eq!(variant.fields(), fields);
+                )*
+            }
+        }
+
+    };
+}
+
+#[allow(unused_macros)]
+macro_rules! test_struct {
+    (
+        $test_name:ident,
+        declare: {
+            $(#[$struct_attr:meta])*
+            {
+                $(
+                    $(#[$attr:meta])* $field:ident: $ty:ty
+                ),* $(,)?
+            }
+        }
+        init: { $($init_block:stmt)* }
+        define: { $( $val_field:ident: $val:expr),* }
+        assert_headers: { $headers:expr }
+        assert_fields: { $fields:expr }
+    ) => {
+
+        #[test]
+        fn $test_name() {
+            $($init_block)*
+
+            #[derive(Tabled)]
+            $(#[$struct_attr])*
+            struct Test {
+                $(
+                    $(#[$attr])*
+                    $field: $ty,
+                )*
+            }
+
+            let value = Test {
+                $($val_field: $val,)*
+            };
+
+            let fields: Vec<&'static str> = $fields.to_vec();
+            let headers: Vec<&'static str> = $headers.to_vec();
+            assert_eq!(Test::headers(), headers);
+            assert_eq!(value.fields(), fields);
+            assert_eq!(<Test as Tabled>::LENGTH, headers.len());
+            assert_eq!(<Test as Tabled>::LENGTH, fields.len());
+        }
+    };
+
+}
+
+#[allow(non_camel_case_types)]
+#[allow(dead_code)]
+pub(crate) type sstr = &'static str;
+
+#[allow(unused_imports)]
+pub(crate) use test_enum;
+#[allow(unused_imports)]
+pub(crate) use test_struct;
+#[allow(unused_imports)]
+pub(crate) use test_tuple;
diff --git a/tabled/tests/derive/order_test.rs b/tabled/tests/derive/order_test.rs
new file mode 100644
index 0000000..6138b53
--- /dev/null
+++ b/tabled/tests/derive/order_test.rs
@@ -0,0 +1,78 @@
+#![cfg(feature = "derive")]
+
+use tabled::Tabled;
+
+use super::{test_enum, test_struct, test_tuple};
+
+test_tuple!(tuple_order_0,  declare: { { #[tabled(order = 0)] u8 u8 u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["0", "1", "2"] } assert_fields: { ["0", "1", "2"] });
+test_tuple!(tuple_order_1,  declare: { { #[tabled(order = 1)] u8 u8 u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["1", "0", "2"] } assert_fields: { ["1", "0", "2"] });
+test_tuple!(tuple_order_2,  declare: { { #[tabled(order = 2)] u8 u8 u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["1", "2", "0"] } assert_fields: { ["1", "2", "0"] });
+test_tuple!(tuple_order_3,  declare: { { u8 #[tabled(order = 0)] u8 u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["1", "0", "2"] } assert_fields: { ["1", "0", "2"] });
+test_tuple!(tuple_order_4,  declare: { { u8 #[tabled(order = 1)] u8 u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["0", "1", "2"] } assert_fields: { ["0", "1", "2"] });
+test_tuple!(tuple_order_5,  declare: { { u8 #[tabled(order = 2)] u8 u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["0", "2", "1"] } assert_fields: { ["0", "2", "1"] });
+test_tuple!(tuple_order_6,  declare: { { u8 u8 #[tabled(order = 0)] u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["2", "0", "1"] } assert_fields: { ["2", "0", "1"] });
+test_tuple!(tuple_order_7,  declare: { { u8 u8 #[tabled(order = 1)] u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["0", "2", "1"] } assert_fields: { ["0", "2", "1"] });
+test_tuple!(tuple_order_8,  declare: { { u8 u8 #[tabled(order = 2)] u8} }                                           init: {} define: { 0 1 2 } assert_headers: { ["0", "1", "2"] } assert_fields: { ["0", "1", "2"] });
+test_tuple!(tuple_order_9,  declare: { { #[tabled(order = 2)] u8 u8 #[tabled(order = 0)] u8} }                      init: {} define: { 0 1 2 } assert_headers: { ["2", "1", "0"] } assert_fields: { ["2", "1", "0"] });
+test_tuple!(tuple_order_10, declare: { { #[tabled(order = 2)] u8 #[tabled(order = 1)] u8 u8} }                      init: {} define: { 0 1 2 } assert_headers: { ["2", "1", "0"] } assert_fields: { ["2", "1", "0"] });
+test_tuple!(tuple_order_11, declare: { { #[tabled(order = 2)] u8 #[tabled(order = 2)] u8 #[tabled(order = 1)] u8} } init: {} define: { 0 1 2 } assert_headers: { ["0", "2", "1"] } assert_fields: { ["0", "2", "1"] });
+test_tuple!(tuple_order_12, declare: { { #[tabled(order = 2)] u8 #[tabled(order = 2)] u8 #[tabled(order = 2)] u8} } init: {} define: { 0 1 2 } assert_headers: { ["0", "1", "2"] } assert_fields: { ["0", "1", "2"] });
+test_tuple!(tuple_order_13, declare: { { #[tabled(order = 1)] u8 #[tabled(order = 1)] u8 #[tabled(order = 1)] u8} } init: {} define: { 0 1 2 } assert_headers: { ["0", "2", "1"] } assert_fields: { ["0", "2", "1"] });
+test_tuple!(tuple_order_14, declare: { { #[tabled(order = 2)] u8 #[tabled(order = 1)] u8 #[tabled(order = 0)] u8} } init: {} define: { 0 1 2 } assert_headers: { ["2", "1", "0"] } assert_fields: { ["2", "1", "0"] });
+
+test_enum!(enum_order_0,  declare: { { #[tabled(order = 0)] V1(u8) V2(u8) V3(u8) } }                                           init: {} assert_headers: { ["V1", "V2", "V3"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
+test_enum!(enum_order_1,  declare: { { #[tabled(order = 1)] V1(u8) V2(u8) V3(u8) } }                                           init: {} assert_headers: { ["V2", "V1", "V3"] } assert: { V1(0) => ["", "+", ""], V2(0) => ["+", "", ""], V3(0) => ["", "", "+"],});
+test_enum!(enum_order_2,  declare: { { #[tabled(order = 2)] V1(u8) V2(u8) V3(u8) } }                                           init: {} assert_headers: { ["V2", "V3", "V1"] } assert: { V1(0) => ["", "", "+"], V2(0) => ["+", "", ""], V3(0) => ["", "+", ""],});
+test_enum!(enum_order_3,  declare: { { V1(u8) #[tabled(order = 0)] V2(u8) V3(u8) } }                                           init: {} assert_headers: { ["V2", "V1", "V3"] } assert: { V1(0) => ["", "+", ""], V2(0) => ["+", "", ""], V3(0) => ["", "", "+"],});
+test_enum!(enum_order_4,  declare: { { V1(u8) #[tabled(order = 1)] V2(u8) V3(u8) } }                                           init: {} assert_headers: { ["V1", "V2", "V3"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
+test_enum!(enum_order_5,  declare: { { V1(u8) #[tabled(order = 2)] V2(u8) V3(u8) } }                                           init: {} assert_headers: { ["V1", "V3", "V2"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
+test_enum!(enum_order_6,  declare: { { V1(u8) V2(u8) #[tabled(order = 0)] V3(u8) } }                                           init: {} assert_headers: { ["V3", "V1", "V2"] } assert: { V1(0) => ["", "+", ""], V2(0) => ["", "", "+"], V3(0) => ["+", "", ""],});
+test_enum!(enum_order_7,  declare: { { V1(u8) V2(u8) #[tabled(order = 1)] V3(u8) } }                                           init: {} assert_headers: { ["V1", "V3", "V2"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
+test_enum!(enum_order_8,  declare: { { V1(u8) V2(u8) #[tabled(order = 2)] V3(u8) } }                                           init: {} assert_headers: { ["V1", "V2", "V3"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
+test_enum!(enum_order_9,  declare: { { #[tabled(order = 2)] V1(u8) V2(u8) #[tabled(order = 0)] V3(u8) } }                      init: {} assert_headers: { ["V3", "V2", "V1"] } assert: { V1(0) => ["", "", "+"], V2(0) => ["", "+", ""], V3(0) => ["+", "", ""],});
+test_enum!(enum_order_10, declare: { { #[tabled(order = 2)] V1(u8) V2(u8) #[tabled(order = 1)] V3(u8) } }                      init: {} assert_headers: { ["V2", "V3", "V1"] } assert: { V1(0) => ["", "", "+"], V2(0) => ["+", "", ""], V3(0) => ["", "+", ""],});
+test_enum!(enum_order_11, declare: { { #[tabled(order = 2)] V1(u8) #[tabled(order = 2)] V2(u8) #[tabled(order = 1)] V3(u8) } } init: {} assert_headers: { ["V1", "V3", "V2"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
+test_enum!(enum_order_12, declare: { { #[tabled(order = 2)] V1(u8) #[tabled(order = 1)] V2(u8) #[tabled(order = 0)] V3(u8) } } init: {} assert_headers: { ["V3", "V2", "V1"] } assert: { V1(0) => ["", "", "+"], V2(0) => ["", "+", ""], V3(0) => ["+", "", ""],});
+test_enum!(enum_order_13, declare: { { #[tabled(order = 0)] V1(u8) #[tabled(order = 0)] V2(u8) #[tabled(order = 0)] V3(u8) } } init: {} assert_headers: { ["V3", "V1", "V2"] } assert: { V1(0) => ["", "+", ""], V2(0) => ["", "", "+"], V3(0) => ["+", "", ""],});
+test_enum!(enum_order_14, declare: { { #[tabled(order = 1)] V1(u8) #[tabled(order = 1)] V2(u8) #[tabled(order = 1)] V3(u8) } } init: {} assert_headers: { ["V1", "V3", "V2"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],});
+test_enum!(enum_order_15, declare: { { #[tabled(order = 2)] V1(u8) #[tabled(order = 2)] V2(u8) #[tabled(order = 2)] V3(u8) } } init: {} assert_headers: { ["V1", "V2", "V3"] } assert: { V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],});
+
+test_struct!(struct_order_0,  declare: { { #[tabled(order = 0)] f0: u8, f1: u8, f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f0", "f1", "f2"] } assert_fields: { ["0", "1", "2"] } );
+test_struct!(struct_order_1,  declare: { { #[tabled(order = 1)] f0: u8, f1: u8, f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f1", "f0", "f2"] } assert_fields: { ["1", "0", "2"] } );
+test_struct!(struct_order_2,  declare: { { #[tabled(order = 2)] f0: u8, f1: u8, f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f1", "f2", "f0"] } assert_fields: { ["1", "2", "0"] } );
+test_struct!(struct_order_3,  declare: { { f0: u8, #[tabled(order = 0)] f1: u8, f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f1", "f0", "f2"] } assert_fields: { ["1", "0", "2"] } );
+test_struct!(struct_order_4,  declare: { { f0: u8, #[tabled(order = 1)] f1: u8, f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f0", "f1", "f2"] } assert_fields: { ["0", "1", "2"] } );
+test_struct!(struct_order_5,  declare: { { f0: u8, #[tabled(order = 2)] f1: u8, f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f0", "f2", "f1"] } assert_fields: { ["0", "2", "1"] } );
+test_struct!(struct_order_6,  declare: { { f0: u8, f1: u8, #[tabled(order = 0)] f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f2", "f0", "f1"] } assert_fields: { ["2", "0", "1"] } );
+test_struct!(struct_order_7,  declare: { { f0: u8, f1: u8, #[tabled(order = 1)] f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f0", "f2", "f1"] } assert_fields: { ["0", "2", "1"] } );
+test_struct!(struct_order_8,  declare: { { f0: u8, f1: u8, #[tabled(order = 2)] f2: u8 } }                                           init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f0", "f1", "f2"] } assert_fields: { ["0", "1", "2"] } );
+test_struct!(struct_order_9,  declare: { { #[tabled(order = 2)] f0: u8, f1: u8, #[tabled(order = 0)] f2: u8 } }                      init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f2", "f1", "f0"] } assert_fields: { ["2", "1", "0"] } );
+test_struct!(struct_order_10, declare: { { #[tabled(order = 2)] f0: u8, #[tabled(order = 1)] f1: u8, f2: u8 } }                      init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f2", "f1", "f0"] } assert_fields: { ["2", "1", "0"] } );
+test_struct!(struct_order_11, declare: { { #[tabled(order = 2)] f0: u8, #[tabled(order = 2)] f1: u8, #[tabled(order = 1)] f2: u8 } } init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f0", "f2", "f1"] } assert_fields: { ["0", "2", "1"] } );
+test_struct!(struct_order_12, declare: { { #[tabled(order = 2)] f0: u8, #[tabled(order = 1)] f1: u8, #[tabled(order = 0)] f2: u8 } } init: {} define: { f0: 0, f1: 1, f2: 2 } assert_headers: { ["f2", "f1", "f0"] } assert_fields: { ["2", "1", "0"] } );
+
+#[test]
+fn test_order_skip_usage() {
+    #[derive(Tabled, Default)]
+    pub struct Example {
+        #[tabled(skip)]
+        #[allow(dead_code)]
+        id: usize,
+        name: String,
+        #[tabled(order = 0)]
+        details: String,
+    }
+
+    #[derive(Tabled, Default)]
+    pub struct Example2 {
+        #[tabled(skip)]
+        #[allow(dead_code)]
+        id: usize,
+        name: String,
+        #[tabled(order = 1)]
+        details: String,
+    }
+
+    assert_eq!(Example::headers(), vec!["details", "name"],);
+    assert_eq!(Example::default().fields(), vec!["", ""]);
+}
diff --git a/tabled/tests/derive/rename_all_test.rs b/tabled/tests/derive/rename_all_test.rs
new file mode 100644
index 0000000..6e87162
--- /dev/null
+++ b/tabled/tests/derive/rename_all_test.rs
@@ -0,0 +1,174 @@
+#![cfg(feature = "derive")]
+
+use tabled::Tabled;
+
+use super::{sstr, test_enum, test_struct, test_tuple};
+
+test_tuple!(
+    tuple_rename_all,
+    declare: { #[tabled(rename_all = "UPPERCASE")] { u8 sstr } }
+    init: {}
+    define: { 0 "123" }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "123"] }
+);
+
+test_tuple!(
+    tuple_rename_all_field,
+    declare: { { u8 #[tabled(rename_all = "UPPERCASE")] sstr } }
+    init: { }
+    define: { 0 "123" }
+    assert_headers: { ["0", "1"] }
+    assert_fields: { ["0", "123"] }
+);
+
+test_tuple!(
+    tuple_rename_all_field_with_rename_0,
+    declare: { { u8 #[tabled(rename_all = "UPPERCASE", rename = "Something")] sstr } }
+    init: {}
+    define: { 0 "123" }
+    assert_headers: { ["0", "Something"] }
+    assert_fields: { ["0", "123"] }
+);
+
+test_tuple!(
+    tuple_rename_all_field_with_rename_1,
+    declare: { { u8 #[tabled(rename = "Something")] #[tabled(rename_all = "UPPERCASE")] sstr } }
+    init: { }
+    define: { 0 "123" }
+    assert_headers: { ["0", "Something"] }
+    assert_fields: { ["0", "123"] }
+);
+
+test_enum!(
+    rename_all_variant,
+    declare: {
+        {
+            #[tabled(rename_all = "snake_case")]
+            VariantName1 { a: u8, b: i32 }
+            #[tabled(rename_all = "UPPERCASE")]
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["variant_name1", "VARIANTNAME2", "VariantName3"] }
+    assert: {
+        VariantName1 { a: 0, b: -1 } => ["+", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "+", ""],
+        VariantName3 => ["", "", "+"],
+    }
+);
+
+test_enum!(
+    rename_all_enum,
+    declare: {
+        #[tabled(rename_all = "snake_case")]
+        {
+            VariantName1 { a: u8, b: i32 }
+            VariantName2(String)
+            VariantName3
+        }
+    }
+    init: {}
+    assert_headers: { ["variant_name1", "variant_name2", "variant_name3"] }
+    assert: {
+        VariantName1 { a: 0, b: -1 } => ["+", "", ""],
+        VariantName2(String::from("Hello World")) => ["", "+", ""],
+        VariantName3 => ["", "", "+"],
+    }
+);
+
+test_struct!(
+    struct_rename_all,
+    declare: { #[tabled(rename_all = "UPPERCASE")] { f1: u8, f2: sstr } }
+    init: {}
+    define: { f1: 0, f2: "v2" }
+    assert_headers: { ["F1", "F2"] }
+    assert_fields: { ["0", "v2"] }
+);
+
+test_struct!(
+    struct_rename_all_override_in_field_by_rename,
+    declare: { #[tabled(rename_all = "UPPERCASE")] { #[tabled(rename = "213213")] f1: u8, f2: sstr } }
+    init: {}
+    define: { f1: 0, f2: "v2" }
+    assert_headers: { ["213213", "F2"] }
+    assert_fields: { ["0", "v2"] }
+);
+
+test_struct!(
+    struct_rename_all_override_in_field_by_rename_all,
+    declare: { #[tabled(rename_all = "UPPERCASE")] { #[tabled(rename_all = "lowercase")] f1: u8, f2: sstr } }
+    init: {}
+    define: { f1: 0, f2: "v2" }
+    assert_headers: { ["f1", "F2"] }
+    assert_fields: { ["0", "v2"] }
+);
+
+test_struct!(
+    struct_rename_all_field,
+    declare: { { #[tabled(rename_all = "lowercase")] f1: u8, #[tabled(rename_all = "UPPERCASE")] f2: sstr } }
+    init: {}
+    define: { f1: 0, f2: "v2" }
+    assert_headers: { ["f1", "F2"] }
+    assert_fields: { ["0", "v2"] }
+);
+
+test_struct!(
+    struct_rename_all_field_overridden_by_rename,
+    declare: { { #[tabled(rename_all = "lowercase", rename = "Hello")] f1: u8, #[tabled(rename_all = "UPPERCASE")] f2: sstr } }
+    init: {}
+    define: { f1: 0, f2: "v2" }
+    assert_headers: { ["Hello", "F2"] }
+    assert_fields: { ["0", "v2"] }
+);
+
+#[test]
+fn rename_all_variants() {
+    macro_rules! test_case {
+        ( $name:ident, $case:expr ) => {
+            #[allow(dead_code)]
+            #[derive(Tabled)]
+            #[tabled(rename_all = $case)]
+            struct $name {
+                field: usize,
+            }
+        };
+    }
+
+    test_case!(S1, "UPPERCASE");
+    test_case!(S2, "lowercase");
+    test_case!(S3, "camelCase");
+    test_case!(S4, "PascalCase");
+    test_case!(S5, "snake_case");
+    test_case!(S6, "SCREAMING_SNAKE_CASE");
+    test_case!(S7, "kebab-case");
+    test_case!(S8, "verbatimcase");
+}
+
+#[test]
+fn rename_all_gets_last_value() {
+    #[derive(Tabled)]
+    #[tabled(rename_all = "UPPERCASE")]
+    #[tabled(rename_all = "PascalCase")]
+    struct Struct1 {
+        field: usize,
+    }
+
+    let st = Struct1 { field: 789 };
+
+    assert_eq!(Struct1::headers(), vec!["Field"],);
+    assert_eq!(st.fields(), vec!["789"]);
+
+    #[derive(Tabled)]
+    #[tabled(rename_all = "UPPERCASE", rename_all = "PascalCase")]
+    struct Struct2 {
+        field: usize,
+    }
+
+    let st = Struct2 { field: 789 };
+
+    assert_eq!(Struct1::headers(), vec!["Field"],);
+    assert_eq!(st.fields(), vec!["789"]);
+}
diff --git a/tabled/tests/derive/rename_test.rs b/tabled/tests/derive/rename_test.rs
new file mode 100644
index 0000000..43cd170
--- /dev/null
+++ b/tabled/tests/derive/rename_test.rs
@@ -0,0 +1,42 @@
+#![cfg(feature = "derive")]
+
+use tabled::Tabled;
+
+use super::{sstr, test_enum, test_struct, test_tuple};
+
+test_tuple!(
+    tuple_rename,
+    declare: { { u8 #[tabled(rename = "field 2")] sstr } }
+    init: {}
+    define: { 0 "123" }
+    assert_headers: { ["0", "field 2"] }
+    assert_fields: { ["0", "123"] }
+);
+
+test_enum!(
+    enum_rename_variant,
+    declare: { { #[tabled(rename = "Variant 1")] A { a: u8, b: i32 } #[tabled(rename = "Variant 2")] B(sstr) K } }
+    init: {}
+    assert_headers: { ["Variant 1", "Variant 2", "K"] }
+    assert: {
+        A { a: 1, b: 2 } => ["+", "", ""],
+        B("") => ["", "+",  ""],
+        K => ["", "", "+"],
+    }
+);
+
+test_struct!(
+    struct_rename,
+    declare: {
+        {
+            #[tabled(rename = "field 1")]
+            f1: u8,
+            #[tabled(rename = "field 2")]
+            f2: sstr,
+        }
+    }
+    init: {}
+    define: { f1: 0, f2: "v2" }
+    assert_headers: { ["field 1", "field 2"] }
+    assert_fields: { ["0", "v2"] }
+);
diff --git a/tabled/tests/derive/skip_test.rs b/tabled/tests/derive/skip_test.rs
new file mode 100644
index 0000000..db95883
--- /dev/null
+++ b/tabled/tests/derive/skip_test.rs
@@ -0,0 +1,195 @@
+#![cfg(feature = "derive")]
+
+use tabled::Tabled;
+
+use super::{sstr, test_enum, test_struct, test_tuple};
+
+test_tuple!(
+    tuple_skip_0,
+    declare: {
+        {
+            #[tabled(skip)]
+            #[allow(dead_code)]
+            u8
+            #[tabled(rename = "...", skip)]
+            #[allow(dead_code)]
+            sstr
+            sstr
+        }
+    }
+    init: {}
+    define: { 0 "v2" "123" }
+    assert_headers: { ["2"] }
+    assert_fields: { ["123"] }
+);
+
+test_tuple!(
+    tuple_skip_1,
+    declare: {
+        {
+            #[tabled(skip)]
+            #[allow(dead_code)]
+            u8
+            #[tabled(skip)]
+            #[tabled(rename = "...")]
+            #[allow(dead_code)]
+            sstr
+            sstr
+        }
+    }
+    init: {}
+    define: { 0 "v2" "123" }
+    assert_headers: { ["2"] }
+    assert_fields: { ["123"] }
+);
+
+test_enum!(
+    enum_skip_variant,
+    declare: {
+        #[allow(dead_code)]
+        {
+            A { a: u8, b: i32 }
+            #[tabled(skip)]
+            B(sstr)
+            K
+        }
+    }
+    init: {}
+    assert_headers: { ["A", "K"] }
+    assert: {
+        A { a: 1, b: 2 } => ["+", ""],
+        B("") => ["", ""],
+        K => ["", "+"],
+    }
+);
+
+test_struct!(
+    struct_skip,
+    declare: {
+        {
+            #[tabled(skip)]
+            #[allow(dead_code)]
+            f1: u8,
+            #[tabled(rename = "field 2", skip)]
+            #[allow(dead_code)]
+            f2: sstr,
+            f3: sstr,
+        }
+    }
+    init: {}
+    define: { f1: 0, f2: "v2", f3: "123" }
+    assert_headers: { ["f3"] }
+    assert_fields: { ["123"] }
+);
+
+test_struct!(
+    struct_skip_true,
+    declare: {
+        {
+            #[tabled(skip = true)]
+            #[allow(dead_code)]
+            f1: u8,
+            #[tabled(rename = "field 2", skip = true)]
+            #[allow(dead_code)]
+            f2: sstr,
+            f3: sstr,
+        }
+    }
+    init: {}
+    define: { f1: 0, f2: "v2", f3: "123" }
+    assert_headers: { ["f3"] }
+    assert_fields: { ["123"] }
+);
+
+test_tuple!(
+    tuple_skipped_fields_not_implement_display_tuple,
+    declare: { { #[tabled(skip)] () sstr } }
+    init: {}
+    define: { () "123" }
+    assert_headers: { ["1"] }
+    assert_fields: { ["123"] }
+);
+
+test_struct!(
+    struct_skipped_fields_not_implement_display_struct,
+    declare: { { #[tabled(skip)] _unit: (), s: sstr } }
+    init: {}
+    define: { _unit: (), s: "123" }
+    assert_headers: { ["s"] }
+    assert_fields: { ["123"] }
+);
+
+test_struct!(
+    struct_skipped_fields_not_implement_display_struct_in_inline,
+    declare: { { s: sstr, #[tabled(inline)] f: S1 } }
+    init: {
+        #[derive(Tabled)]
+        struct S1 {
+            #[tabled(skip)]
+            _unit: (),
+            s: sstr,
+        }
+    }
+    define: { s: "123", f: S1 { _unit: (), s: "..." } }
+    assert_headers: { ["s", "s"] }
+    assert_fields: { ["123", "..."] }
+);
+
+#[test]
+fn test_skip_enum_0() {
+    #[allow(dead_code)]
+    #[derive(Tabled)]
+    enum Letters {
+        Vowels {
+            character: char,
+            lang: u8,
+        },
+        Consonant(char),
+        #[tabled(skip)]
+        Digit,
+    }
+
+    assert_eq!(Letters::headers(), vec!["Vowels", "Consonant"]);
+    assert_eq!(Letters::Consonant('c').fields(), vec!["", "+"]);
+    assert_eq!(Letters::Digit.fields(), vec!["", ""]);
+}
+
+#[test]
+fn test_reimport_trait_by_crate_attribute() {
+    pub mod new_module {
+        pub trait Tabled {
+            const LENGTH: usize;
+
+            fn fields(&self) -> Vec<std::borrow::Cow<'_, str>>;
+            fn headers() -> Vec<std::borrow::Cow<'static, str>>;
+        }
+    }
+
+    mod tabled {}
+
+    #[allow(dead_code)]
+    #[derive(Tabled)]
+    #[tabled(crate = "new_module")]
+    enum Letters {
+        Vowels {
+            character: char,
+            lang: u8,
+        },
+        Consonant(char),
+        #[tabled(skip)]
+        Digit,
+    }
+
+    assert_eq!(
+        <Letters as new_module::Tabled>::headers(),
+        vec!["Vowels", "Consonant"]
+    );
+    assert_eq!(
+        <Letters as new_module::Tabled>::fields(&Letters::Consonant('c')),
+        vec!["", "+"]
+    );
+    assert_eq!(
+        <Letters as new_module::Tabled>::fields(&Letters::Digit),
+        vec!["", ""]
+    );
+}