Repository: zhiburt/tabled
Pull request #418 (2024-07-18 15:27:03)

Rework `#[tabled(format(""))` macro && refactorings
@strange-dv Look at this

I actually wasn't expecting to achieve it but here we are.

```rust
use tabled::{settings::Style, Table, Tabled};

#[derive(Tabled)]
struct User {
    #[tabled(format("{}.{}.{}.{}", self.ip[0], self.ip[1], self.ip[2], self.ip[3]))]
    ip: [u8; 4],
    mask: String,
    password: String,
}

impl User {
    fn new(ip: [u8; 4], mask: &str, password: &str) -> Self {
        Self {
            ip,
            mask: mask.to_string(),
            password: password.to_string(),
        }
    }
}

fn main() {
    let data = [
        User::new([127, 0, 0, 1], "", "11111111"),
        User::new([127, 0, 0, 1], "", "22222222"),
        User::new([127, 0, 0, 1], "", "33333333"),
        User::new([127, 0, 0, 1], "", "44444444"),
    ];

    let mut table = Table::new(data);
    table.with(
        Style::modern_rounded()
            .remove_horizontal()
            .remove_vertical(),
    );

    println!("{table}");
}
```

```text
╭───────────────────────────╮
│ ip         mask  password │
│ 127.0.0.1        11111111 │
│ 127.0.0.1        22222222 │
│ 127.0.0.1        33333333 │
│ 127.0.0.1        44444444 │
╰───────────────────────────╯
```


Patch:
diff --git a/tabled/Cargo.toml b/tabled/Cargo.toml
index 8032161..10835f9 100644
--- a/tabled/Cargo.toml
+++ b/tabled/Cargo.toml
@@ -78,6 +78,11 @@ name = "derive_format"
 path = "examples/derive/format.rs"
 required-features = ["derive"]
 
+[[example]]
+name = "derive_format2"
+path = "examples/derive/format2.rs"
+required-features = ["derive"]
+
 [[example]]
 name = "table"
 path = "examples/table.rs"
diff --git a/tabled/examples/derive/display_with.rs b/tabled/examples/derive/display_with.rs
index 9dfc87a..c011801 100644
--- a/tabled/examples/derive/display_with.rs
+++ b/tabled/examples/derive/display_with.rs
@@ -18,6 +18,7 @@ use tabled::{Table, Tabled};
 #[tabled(rename_all = "camelCase")]
 struct Country {
     name: &'static str,
+    #[tabled(display_with("display_capital", format!("CAPITAL {}", self.capital_city)))]
     capital_city: &'static str,
     #[tabled(display_with("display_perimeter", self))]
     surface_area_km2: f32,
@@ -34,6 +35,10 @@ fn display_perimeter(country: &Country) -> Cow<'_, str> {
     }
 }
 
+fn display_capital(country: String) -> Cow<'static, str> {
+    format!("{country}!").into()
+}
+
 impl Country {
     fn new(
         name: &'static str,
diff --git a/tabled/examples/derive/format.rs b/tabled/examples/derive/format.rs
index d69fb0a..0dc31cd 100644
--- a/tabled/examples/derive/format.rs
+++ b/tabled/examples/derive/format.rs
@@ -9,7 +9,7 @@ struct Phone {
     code: String,
     #[tabled(skip)]
     alias: String,
-    #[tabled(format("{}/{}", self.alias, self.number))]
+    #[tabled(format("{}/{}", str::to_lowercase(&self.alias), self.number))]
     number: String,
 }
 
diff --git a/tabled/examples/derive/format2.rs b/tabled/examples/derive/format2.rs
new file mode 100644
index 0000000..5550dd7
--- /dev/null
+++ b/tabled/examples/derive/format2.rs
@@ -0,0 +1,61 @@
+//! This example demonstrates using the [attribute macro](https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros)
+//! [`format`] to beatifuly castomize the resulting values, be used for table contraction.
+
+use tabled::{settings::Style, Table, Tabled};
+
+#[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 {}", str::to_uppercase(self.text)))]
+        text: String,
+        #[tabled(format = "F {}")]
+        factor: usize,
+    },
+    #[tabled(inline)]
+    Plain(String),
+}
+
+impl Password {
+    fn mask(s: &str, f: usize) -> Self {
+        Self::Mask {
+            text: s.to_string(),
+            factor: f,
+        }
+    }
+
+    fn plain(s: &str) -> Self {
+        Self::Plain(s.to_string())
+    }
+}
+
+impl User {
+    fn new(ip: [u8; 4], password: Password) -> Self {
+        Self { ip, password }
+    }
+}
+
+fn main() {
+    let data = [
+        User::new([127, 0, 0, 1], Password::mask("11111111", 0)),
+        User::new([127, 0, 0, 1], Password::mask("1", 1000)),
+        User::new([127, 0, 0, 3], Password::plain("3333")),
+    ];
+
+    let mut table = Table::new(data);
+    table.with(
+        Style::modern_rounded()
+            .remove_horizontal()
+            .remove_vertical(),
+    );
+
+    println!("{table}");
+}
diff --git a/tabled_derive/Cargo.toml b/tabled_derive/Cargo.toml
index 6125a54..f2b66b5 100644
--- a/tabled_derive/Cargo.toml
+++ b/tabled_derive/Cargo.toml
@@ -11,7 +11,7 @@ license = "MIT"
 proc-macro = true
 
 [dependencies]
-syn = "1"
+syn = { version = "1", features = ["full", "visit-mut"] }
 quote = "1"
 proc-macro2 = "1"
 heck = "0.4"
diff --git a/tabled_derive/src/attributes.rs b/tabled_derive/src/attributes.rs
deleted file mode 100644
index b1bcbc5..0000000
--- a/tabled_derive/src/attributes.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-use syn::{Attribute, Lit, LitInt};
-
-use crate::{
-    casing_style::CasingStyle,
-    error::Error,
-    parse::{
-        field_attr::{parse_field_attributes, FieldAttr, FieldAttrKind},
-        type_attr::{parse_type_attributes, TypeAttr, TypeAttrKind},
-    },
-};
-
-#[derive(Debug, Default)]
-pub struct FieldAttributes {
-    pub is_ignored: bool,
-    pub inline: bool,
-    pub inline_prefix: Option<String>,
-    pub rename: Option<String>,
-    pub rename_all: Option<CasingStyle>,
-    pub display_with: Option<String>,
-    pub display_with_args: Option<Vec<FuncArg>>,
-    pub order: Option<usize>,
-    pub format: Option<String>,
-    pub format_with_args: Option<Vec<FuncArg>>,
-}
-
-impl FieldAttributes {
-    pub fn parse(attrs: &[Attribute]) -> Result<Self, Error> {
-        let mut attributes = Self::default();
-        attributes.fill_attributes(attrs)?;
-
-        Ok(attributes)
-    }
-
-    fn fill_attributes(&mut self, attrs: &[Attribute]) -> Result<(), Error> {
-        for attrs in parse_field_attributes(attrs) {
-            let attrs = attrs?;
-            for attr in attrs {
-                self.insert_attribute(attr)?;
-            }
-        }
-
-        Ok(())
-    }
-
-    fn insert_attribute(&mut self, attr: FieldAttr) -> Result<(), Error> {
-        match attr.kind {
-            FieldAttrKind::Skip(b) => {
-                if b.value {
-                    self.is_ignored = true;
-                }
-            }
-            FieldAttrKind::Inline(b, prefix) => {
-                if b.value {
-                    self.inline = true;
-                }
-
-                if let Some(prefix) = prefix {
-                    self.inline_prefix = Some(prefix.value());
-                }
-            }
-            FieldAttrKind::Rename(value) => self.rename = Some(value.value()),
-            FieldAttrKind::RenameAll(lit) => {
-                self.rename_all = Some(CasingStyle::from_lit(&lit)?);
-            }
-            FieldAttrKind::DisplayWith(path, comma, args) => {
-                self.display_with = Some(path.value());
-                if comma.is_some() {
-                    let args = args
-                        .into_iter()
-                        .map(|lit| parse_func_arg(&lit))
-                        .collect::<Result<Vec<_>, _>>()?;
-                    self.display_with_args = Some(args);
-                }
-            }
-            FieldAttrKind::FormatWith(format, comma, args) => {
-                self.format = Some(format.value());
-                if comma.is_some() {
-                    let args = args
-                        .into_iter()
-                        .map(|lit| parse_func_arg(&lit))
-                        .collect::<Result<Vec<_>, _>>()?;
-                    self.format_with_args = Some(args);
-                }
-            }
-            FieldAttrKind::Order(value) => self.order = Some(lit_int_to_usize(&value)?),
-        }
-
-        Ok(())
-    }
-}
-
-#[derive(Debug, Default)]
-pub struct TypeAttributes {
-    pub rename_all: Option<CasingStyle>,
-    pub inline: bool,
-    pub inline_value: Option<String>,
-    pub crate_name: Option<String>,
-}
-
-impl TypeAttributes {
-    pub fn parse(attrs: &[Attribute]) -> Result<Self, Error> {
-        let mut attributes = Self::default();
-        attributes.fill_attributes(attrs)?;
-
-        Ok(attributes)
-    }
-
-    fn fill_attributes(&mut self, attrs: &[Attribute]) -> Result<(), Error> {
-        for attrs in parse_type_attributes(attrs) {
-            let attrs = attrs?;
-            for attr in attrs {
-                self.insert_attribute(attr)?;
-            }
-        }
-
-        Ok(())
-    }
-
-    fn insert_attribute(&mut self, attr: TypeAttr) -> Result<(), Error> {
-        match attr.kind {
-            TypeAttrKind::Crate(crate_name) => {
-                let name = crate_name.value();
-                if !name.is_empty() {
-                    self.crate_name = Some(name);
-                }
-            }
-            TypeAttrKind::Inline(b, prefix) => {
-                if b.value {
-                    self.inline = true;
-                }
-
-                if let Some(prefix) = prefix {
-                    self.inline_value = Some(prefix.value());
-                }
-            }
-            TypeAttrKind::RenameAll(lit) => {
-                self.rename_all = Some(CasingStyle::from_lit(&lit)?);
-            }
-        }
-
-        Ok(())
-    }
-}
-
-fn lit_int_to_usize(value: &LitInt) -> Result<usize, Error> {
-    value.base10_parse::<usize>().map_err(|e| {
-        Error::new(
-            format!("Failed to parse {:?} as usize; {}", value.to_string(), e),
-            value.span(),
-            None,
-        )
-    })
-}
-
-#[derive(Debug)]
-pub enum FuncArg {
-    SelfRef,
-    SelfProperty(String),
-    Byte(u8),
-    Char(char),
-    Bool(bool),
-    Uint(usize),
-    Int(isize),
-    Float(f64),
-    String(String),
-    Bytes(Vec<u8>),
-}
-
-fn parse_func_arg(expr: &syn::Expr) -> syn::Result<FuncArg> {
-    use syn::spanned::Spanned;
-
-    match expr {
-        syn::Expr::Lit(lit) => match &lit.lit {
-            Lit::Str(val) => Ok(FuncArg::String(val.value())),
-            Lit::ByteStr(val) => Ok(FuncArg::Bytes(val.value())),
-            Lit::Byte(val) => Ok(FuncArg::Byte(val.value())),
-            Lit::Char(val) => Ok(FuncArg::Char(val.value())),
-            Lit::Bool(val) => Ok(FuncArg::Bool(val.value())),
-            Lit::Float(val) => val.base10_parse::<f64>().map(FuncArg::Float),
-            Lit::Int(val) => {
-                if val.base10_digits().starts_with('-') {
-                    val.base10_parse::<isize>().map(FuncArg::Int)
-                } else {
-                    val.base10_parse::<usize>().map(FuncArg::Uint)
-                }
-            }
-            Lit::Verbatim(val) => Err(syn::Error::new(val.span(), "unsupported argument")),
-        },
-        syn::Expr::Path(path) => {
-            let indent = path.path.get_ident().map(|indent| indent.to_string());
-            if matches!(indent.as_deref(), Some("self" | "Self")) {
-                Ok(FuncArg::SelfRef)
-            } else {
-                Err(syn::Error::new(path.span(), "unsupported argument"))
-            }
-        }
-        syn::Expr::Field(field) => match &field.member {
-            syn::Member::Named(ident) => Ok(FuncArg::SelfProperty(ident.to_string())),
-            syn::Member::Unnamed(index) => Ok(FuncArg::SelfProperty(index.index.to_string())),
-        },
-        expr => Err(syn::Error::new(expr.span(), "unsupported argument")),
-    }
-}
diff --git a/tabled_derive/src/attributes/field_attr.rs b/tabled_derive/src/attributes/field_attr.rs
new file mode 100644
index 0000000..1eedf77
--- /dev/null
+++ b/tabled_derive/src/attributes/field_attr.rs
@@ -0,0 +1,101 @@
+use syn::{Attribute, LitInt};
+
+use crate::{
+    casing_style::CasingStyle,
+    error::Error,
+    parse::field_attr::{parse_field_attributes, FieldAttr, FieldAttrKind},
+};
+
+#[derive(Default)]
+pub struct FieldAttributes {
+    pub is_ignored: bool,
+    pub inline: bool,
+    pub inline_prefix: Option<String>,
+    pub rename: Option<String>,
+    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 struct FormatArg {
+    pub expr: syn::Expr,
+}
+
+impl FormatArg {
+    pub fn new(expr: syn::Expr) -> Self {
+        Self { expr }
+    }
+}
+
+impl FieldAttributes {
+    pub fn parse(attrs: &[Attribute]) -> Result<Self, Error> {
+        let mut attributes = Self::default();
+        attributes.fill_attributes(attrs)?;
+
+        Ok(attributes)
+    }
+
+    fn fill_attributes(&mut self, attrs: &[Attribute]) -> Result<(), Error> {
+        for attrs in parse_field_attributes(attrs) {
+            let attrs = attrs?;
+            for attr in attrs {
+                self.insert_attribute(attr)?;
+            }
+        }
+
+        Ok(())
+    }
+
+    fn insert_attribute(&mut self, attr: FieldAttr) -> Result<(), Error> {
+        match attr.kind {
+            FieldAttrKind::Skip(b) => {
+                if b.value {
+                    self.is_ignored = true;
+                }
+            }
+            FieldAttrKind::Inline(b, prefix) => {
+                if b.value {
+                    self.inline = true;
+                }
+
+                if let Some(prefix) = prefix {
+                    self.inline_prefix = Some(prefix.value());
+                }
+            }
+            FieldAttrKind::Rename(value) => self.rename = Some(value.value()),
+            FieldAttrKind::RenameAll(lit) => {
+                self.rename_all = Some(CasingStyle::from_lit(&lit)?);
+            }
+            FieldAttrKind::DisplayWith(path, comma, args) => {
+                self.display_with = Some(path.value());
+                if comma.is_some() {
+                    let args = args.into_iter().map(FormatArg::new).collect();
+                    self.display_with_args = Some(args);
+                }
+            }
+            FieldAttrKind::FormatWith(format, comma, args) => {
+                self.format = Some(format.value());
+                if comma.is_some() {
+                    let args = args.into_iter().map(FormatArg::new).collect();
+                    self.format_with_args = Some(args);
+                }
+            }
+            FieldAttrKind::Order(value) => self.order = Some(lit_int_to_usize(&value)?),
+        }
+
+        Ok(())
+    }
+}
+
+fn lit_int_to_usize(value: &LitInt) -> Result<usize, Error> {
+    value.base10_parse::<usize>().map_err(|e| {
+        Error::new(
+            format!("Failed to parse {:?} as usize; {}", value.to_string(), e),
+            value.span(),
+            None,
+        )
+    })
+}
diff --git a/tabled_derive/src/attributes/mod.rs b/tabled_derive/src/attributes/mod.rs
new file mode 100644
index 0000000..6e96fbd
--- /dev/null
+++ b/tabled_derive/src/attributes/mod.rs
@@ -0,0 +1,5 @@
+mod field_attr;
+mod type_attr;
+
+pub use field_attr::{FieldAttributes, FormatArg};
+pub use type_attr::TypeAttributes;
diff --git a/tabled_derive/src/attributes/type_attr.rs b/tabled_derive/src/attributes/type_attr.rs
new file mode 100644
index 0000000..53ccbc9
--- /dev/null
+++ b/tabled_derive/src/attributes/type_attr.rs
@@ -0,0 +1,60 @@
+use syn::Attribute;
+
+use crate::{
+    casing_style::CasingStyle,
+    error::Error,
+    parse::type_attr::{parse_type_attributes, TypeAttr, TypeAttrKind},
+};
+
+#[derive(Debug, Default)]
+pub struct TypeAttributes {
+    pub rename_all: Option<CasingStyle>,
+    pub inline: bool,
+    pub inline_value: Option<String>,
+    pub crate_name: Option<String>,
+}
+
+impl TypeAttributes {
+    pub fn parse(attrs: &[Attribute]) -> Result<Self, Error> {
+        let mut attributes = Self::default();
+        attributes.fill_attributes(attrs)?;
+
+        Ok(attributes)
+    }
+
+    fn fill_attributes(&mut self, attrs: &[Attribute]) -> Result<(), Error> {
+        for attrs in parse_type_attributes(attrs) {
+            let attrs = attrs?;
+            for attr in attrs {
+                self.insert_attribute(attr)?;
+            }
+        }
+
+        Ok(())
+    }
+
+    fn insert_attribute(&mut self, attr: TypeAttr) -> Result<(), Error> {
+        match attr.kind {
+            TypeAttrKind::Crate(crate_name) => {
+                let name = crate_name.value();
+                if !name.is_empty() {
+                    self.crate_name = Some(name);
+                }
+            }
+            TypeAttrKind::Inline(b, prefix) => {
+                if b.value {
+                    self.inline = true;
+                }
+
+                if let Some(prefix) = prefix {
+                    self.inline_value = Some(prefix.value());
+                }
+            }
+            TypeAttrKind::RenameAll(lit) => {
+                self.rename_all = Some(CasingStyle::from_lit(&lit)?);
+            }
+        }
+
+        Ok(())
+    }
+}
diff --git a/tabled_derive/src/lib.rs b/tabled_derive/src/lib.rs
index 0b29225..309d8bd 100644
--- a/tabled_derive/src/lib.rs
+++ b/tabled_derive/src/lib.rs
@@ -10,17 +10,21 @@ mod casing_style;
 mod error;
 mod parse;
 
+use attributes::FormatArg;
 use proc_macro2::TokenStream;
 use proc_macro_error::proc_macro_error;
 use quote::{quote, ToTokens, TokenStreamExt};
 use std::{collections::HashMap, str};
+use syn::visit_mut::VisitMut;
 use syn::{
     parse_macro_input, token, Data, DataEnum, DataStruct, DeriveInput, ExprPath, Field, Fields,
     Ident, Index, PathSegment, Type, Variant,
 };
 
-use attributes::{FieldAttributes, FuncArg, TypeAttributes};
-use error::Error;
+use crate::attributes::{FieldAttributes, TypeAttributes};
+use crate::error::Error;
+
+type FieldNameFn = fn(usize, &Field) -> TokenStream;
 
 #[proc_macro_derive(Tabled, attributes(tabled))]
 #[proc_macro_error]
@@ -168,7 +172,7 @@ fn collect_info_struct(
     attrs: &TypeAttributes,
     trait_path: &ExprPath,
 ) -> Result<Impl, Error> {
-    info_from_fields(&ast.fields, attrs, field_var_name, "", trait_path)
+    info_from_fields(&ast.fields, attrs, struct_field_name, "", trait_path)
 }
 
 // todo: refactoring. instead of using a lambda + prefix
@@ -177,7 +181,7 @@ fn collect_info_struct(
 fn info_from_fields(
     fields: &Fields,
     attrs: &TypeAttributes,
-    field_name: impl Fn(usize, &Field) -> TokenStream,
+    field_name: FieldNameFn,
     header_prefix: &str,
     trait_path: &ExprPath,
 ) -> Result<Impl, Error> {
@@ -219,7 +223,7 @@ fn info_from_fields(
         headers.push(header);
 
         let field_name_result = field_name(i, field);
-        let value = get_field_fields(&field_name_result, &attributes, fields, &field_name);
+        let value = get_field_fields(&field_name_result, &attributes, fields, field_name);
         values.push(value);
     }
 
@@ -394,7 +398,13 @@ fn info_from_variant(
             .inline_prefix
             .as_ref()
             .map_or_else(|| "", |s| s.as_str());
-        return info_from_fields(&variant.fields, attrs, variant_var_name, prefix, trait_path);
+        return info_from_fields(
+            &variant.fields,
+            attrs,
+            variant_field_name,
+            prefix,
+            trait_path,
+        );
     }
 
     let variant_name = variant_name(variant, attr);
@@ -406,7 +416,7 @@ fn info_from_variant(
                 false => {
                     let args = args
                         .iter()
-                        .map(|arg| fnarg_tokens(arg, &Fields::Unit, field_var_name))
+                        .map(|arg| fnarg_tokens(arg, &Fields::Unit, struct_field_name))
                         .collect::<Vec<_>>();
                     Some(quote!( #(#args,)* ))
                 }
@@ -427,7 +437,7 @@ fn info_from_variant(
                 false => {
                     let args = args
                         .iter()
-                        .map(|arg| fnarg_tokens(arg, &Fields::Unit, field_var_name))
+                        .map(|arg| fnarg_tokens(arg, &Fields::Unit, struct_field_name))
                         .collect::<Vec<_>>();
                     Some(quote!( #(#args,)* ))
                 }
@@ -482,7 +492,7 @@ fn get_field_fields(
     field: &TokenStream,
     attr: &FieldAttributes,
     fields: &Fields,
-    field_name: impl Fn(usize, &Field) -> TokenStream,
+    field_name: FieldNameFn,
 ) -> TokenStream {
     if attr.inline {
         return quote! { #field.fields() };
@@ -496,7 +506,7 @@ fn get_field_fields(
                 false => {
                     let args = args
                         .iter()
-                        .map(|arg| fnarg_tokens(arg, fields, &field_name))
+                        .map(|arg| fnarg_tokens(arg, fields, field_name))
                         .collect::<Vec<_>>();
                     Some(quote!( #(#args,)* ))
                 }
@@ -517,7 +527,7 @@ fn get_field_fields(
                 false => {
                     let args = args
                         .iter()
-                        .map(|arg| fnarg_tokens(arg, fields, &field_name))
+                        .map(|arg| fnarg_tokens(arg, fields, field_name))
                         .collect::<Vec<_>>();
                     Some(quote!( #(#args,)* ))
                 }
@@ -569,7 +579,7 @@ fn use_format_no_args(custom_format: &str, field: &TokenStream) -> TokenStream {
     quote! { format!(#custom_format, #field) }
 }
 
-fn field_var_name(index: usize, field: &Field) -> TokenStream {
+fn struct_field_name(index: usize, field: &Field) -> TokenStream {
     let f = field.ident.as_ref().map_or_else(
         || Index::from(index).to_token_stream(),
         quote::ToTokens::to_token_stream,
@@ -577,7 +587,7 @@ fn field_var_name(index: usize, field: &Field) -> TokenStream {
     quote!(self.#f)
 }
 
-fn variant_var_name(index: usize, field: &Field) -> TokenStream {
+fn variant_field_name(index: usize, field: &Field) -> TokenStream {
     match &field.ident {
         Some(indent) => indent.to_token_stream(),
         None => Ident::new(
@@ -648,7 +658,7 @@ fn variant_idents(v: &Variant) -> Vec<TokenStream> {
         .enumerate()
         // we intentionally not ignore these fields to be able to build a pattern correctly
         // .filter(|(_, field)| !Attr::parse(&field.attrs).is_ignored())
-        .map(|(index, field)| variant_var_name(index, field))
+        .map(|(index, field)| variant_field_name(index, field))
         .collect::<Vec<_>>()
 }
 
@@ -711,41 +721,91 @@ fn merge_attributes(attr: &mut FieldAttributes, global_attr: &TypeAttributes) {
     }
 }
 
-fn fnarg_tokens(
-    arg: &FuncArg,
-    fields: &Fields,
-    field_name: impl Fn(usize, &Field) -> TokenStream,
-) -> TokenStream {
-    match arg {
-        FuncArg::SelfRef => quote! { &self },
-        FuncArg::SelfProperty(val) => {
-            let property_name = syn::Ident::new(val, proc_macro2::Span::call_site());
-
-            // We find the corresponding field in the local object fields instead of using self,
-            // which would be a higher level object. This is for nested structures.
-            for (i, field) in fields.iter().enumerate() {
-                let field_name_result = field_name(i, field);
-                if field_name_result.to_string() == *val {
-                    return quote! { #field_name_result };
+// to resolve invocation issues withing a macros calls
+// we need such a workround
+struct ExprSelfReplace<'a>(Option<(&'a Fields, FieldNameFn)>);
+
+impl syn::visit_mut::VisitMut for ExprSelfReplace<'_> {
+    fn visit_expr_mut(&mut self, node: &mut syn::Expr) {
+        match &node {
+            syn::Expr::Path(path) => {
+                let indent = path.path.get_ident();
+                if let Some(indent) = indent {
+                    if indent == "self" {
+                        *node = syn::parse_quote! { (&self) };
+                        return;
+                    }
                 }
             }
-
-            quote! { &self.#property_name }
-        }
-        FuncArg::Byte(val) => quote! { #val },
-        FuncArg::Char(val) => quote! { #val },
-        FuncArg::Bool(val) => quote! { #val },
-        FuncArg::Uint(val) => quote! { #val },
-        FuncArg::Int(val) => quote! { #val },
-        FuncArg::Float(val) => quote! { #val },
-        FuncArg::String(val) => quote! { #val },
-        FuncArg::Bytes(val) => {
-            let val = syn::LitByteStr::new(val, proc_macro2::Span::call_site());
-            quote! { #val }
+            syn::Expr::Field(field) => {
+                // treating a enum variant structs which we can't reference by 'self'
+                if let Some((fields, field_name)) = &self.0 {
+                    // check that it's plain self reference
+
+                    if let syn::Expr::Path(path) = field.base.as_ref() {
+                        let indent = path.path.get_ident();
+                        if let Some(indent) = indent {
+                            if indent != "self" {
+                                return;
+                            }
+                        }
+                    }
+
+                    let used_field = {
+                        match &field.member {
+                            syn::Member::Named(ident) => ident.to_string(),
+                            syn::Member::Unnamed(index) => index.index.to_string(),
+                        }
+                    };
+
+                    // We find the corresponding field in the local object fields instead of using self,
+                    // which would be a higher level object. This is for nested structures.
+
+                    for (i, field) in fields.iter().enumerate() {
+                        let field_name_result = (field_name)(i, field);
+                        let field_name = field
+                            .ident
+                            .as_ref()
+                            .map_or_else(|| i.to_string(), |i| i.to_string());
+                        if field_name == used_field {
+                            *node = syn::parse_quote! { #field_name_result };
+                            return;
+                        }
+                    }
+                }
+            }
+            syn::Expr::Macro(_) => {
+                // NOTE: Can we parse inners of Macros?
+                //
+                // A next example will fail on `self.f1` usage
+                // with such error 'expected value, found module `self`'
+                //
+                // ```
+                // some_macro! {
+                //     struct Something {
+                //         #[tabled(display_with("_", format!("", self.f1)))]
+                //         field: Option<sstr>,
+                //         f1: usize,
+                //     }
+                // }
+                // ```
+            }
+            _ => (),
         }
+
+        // Delegate to the default impl to visit nested expressions.
+        syn::visit_mut::visit_expr_mut(self, node);
     }
 }
 
+fn fnarg_tokens(arg: &FormatArg, fields: &Fields, field_name: FieldNameFn) -> TokenStream {
+    let mut exp = arg.expr.clone();
+
+    ExprSelfReplace(Some((fields, field_name))).visit_expr_mut(&mut exp);
+
+    quote!(#exp)
+}
+
 fn reodered_variants(ast: &DataEnum) -> Result<Vec<&Variant>, Error> {
     let mut reorder = HashMap::new();
     let mut skip = 0;


Test patch:
diff --git a/tabled/tests/derive/derive_test.rs b/tabled/tests/derive/derive_test.rs
index 149e869..5515e68 100644
--- a/tabled/tests/derive/derive_test.rs
+++ b/tabled/tests/derive/derive_test.rs
@@ -7,9 +7,9 @@ use tabled::Tabled;
 macro_rules! test_tuple {
     (
         $test_name:ident,
-        t: $(#[$struct_attr:meta])* { $( $(#[$attr:meta])* $ty:ty)* },
-        init: { $($init:expr)* },
-        expected: $headers:expr, $fields:expr,
+        { $(#[$struct_attr:meta])* { $( $(#[$attr:meta])* $ty:ty)* } },
+        { $($init:expr)* },
+        { $headers:expr, $fields:expr } $(,)?
         $(pre: { $($init_block:stmt)* })?
     ) => {
         #[test]
@@ -17,9 +17,10 @@ macro_rules! test_tuple {
             $($($init_block)*)?
 
             #[derive(Tabled)]
+            $(#[$struct_attr])*
             #[allow(dead_code)]
-            pub struct TestType(
-                $( $(#[$attr]) * $ty, )*
+            struct TestType(
+                $( $(#[$attr])* $ty, )*
             );
 
             let value = TestType($($init,)*);
@@ -38,15 +39,15 @@ macro_rules! test_tuple {
 macro_rules! test_enum {
     (
         $test_name:ident,
-        t: $(#[$struct_attr:meta])* { $( $(#[$var_attr:meta])*  $var:ident $({ $( $(#[$attr:meta])* $field:ident: $ty:ty),* $(,)? })? $(( $( $(#[$attr2:meta])* $ty2:ty),* $(,)? ))? )* },
-        $(pre: { $($init_block:stmt)* })?
-        headers: $headers:expr,
-        tests:  $($init:expr => $expected:expr,)*
+        { $(#[$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)*)?
+            $($init_block)*
 
             #[derive(Tabled)]
             $(#[$struct_attr])*
@@ -82,16 +83,16 @@ macro_rules! test_enum {
 macro_rules! test_struct {
     (
         $test_name:ident,
-        t: $(#[$struct_attr:meta])* { $( $(#[$attr:meta])* $field:ident: $ty:ty),*  $(,)?}
-        $(pre: { $($init_block:stmt)* })?
-        init: { $( $val_field:ident: $val:expr),* $(,)?}
-        expected: $headers:expr, $fields:expr  $(,)?
+        { $(#[$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)*)?
+            $($init_block)*
 
             #[derive(Tabled)]
             $(#[$struct_attr])*
@@ -122,40 +123,41 @@ type sstr = &'static str;
 mod tuple {
     use super::*;
 
-    test_tuple!(basic, t: { u8 sstr }, init: { 0 "v2" }, expected: ["0", "1"], ["0", "v2"],);
-    test_tuple!(empty, t: { }, init: { }, expected: [], [],);
-
-    test_tuple!(rename, t: { u8 #[tabled(rename = "field 2")] sstr }, init: { 0 "123" }, expected: ["0", "field 2"], ["0", "123"],);
-
-    test_tuple!(skip_0, t: { #[tabled(skip)] u8 #[tabled(rename = "field 2", skip)] sstr sstr }, init: { 0 "v2" "123" }, expected: ["2"], ["123"],);
-    test_tuple!(skip_1, t: { #[tabled(skip)] u8 #[tabled(skip)] #[tabled(rename = "field 2")] sstr sstr }, init: { 0 "v2" "123" }, expected: ["2"], ["123"],);
-
-    test_tuple!(order_0, t: { #[tabled(order = 0)] u8 u8 u8}, init: { 0 1 2 }, expected: ["0", "1", "2"], ["0", "1", "2"],);
-    test_tuple!(order_1, t: { #[tabled(order = 1)] u8 u8 u8}, init: { 0 1 2 }, expected: ["1", "0", "2"], ["1", "0", "2"],);
-    test_tuple!(order_2, t: { #[tabled(order = 2)] u8 u8 u8}, init: { 0 1 2 }, expected: ["1", "2", "0"], ["1", "2", "0"],);
-    test_tuple!(order_3, t: { u8 #[tabled(order = 0)] u8 u8}, init: { 0 1 2 }, expected: ["1", "0", "2"], ["1", "0", "2"],);
-    test_tuple!(order_4, t: { u8 #[tabled(order = 1)] u8 u8}, init: { 0 1 2 }, expected: ["0", "1", "2"], ["0", "1", "2"],);
-    test_tuple!(order_5, t: { u8 #[tabled(order = 2)] u8 u8}, init: { 0 1 2 }, expected: ["0", "2", "1"], ["0", "2", "1"],);
-    test_tuple!(order_6, t: { u8 u8 #[tabled(order = 0)] u8}, init: { 0 1 2 }, expected: ["2", "0", "1"], ["2", "0", "1"],);
-    test_tuple!(order_7, t: { u8 u8 #[tabled(order = 1)] u8}, init: { 0 1 2 }, expected: ["0", "2", "1"], ["0", "2", "1"],);
-    test_tuple!(order_8, t: { u8 u8 #[tabled(order = 2)] u8}, init: { 0 1 2 }, expected: ["0", "1", "2"], ["0", "1", "2"],);
-    test_tuple!(order_9, t: { #[tabled(order = 2)] u8 u8 #[tabled(order = 0)] u8}, init: { 0 1 2 }, expected: ["2", "1", "0"], ["2", "1", "0"],);
-    test_tuple!(order_10, t: { #[tabled(order = 2)] u8 #[tabled(order = 1)] u8 u8}, init: { 0 1 2 }, expected: ["2", "1", "0"], ["2", "1", "0"],);
-    test_tuple!(order_11, t: { #[tabled(order = 2)] u8 #[tabled(order = 2)] u8 #[tabled(order = 1)] u8}, init: { 0 1 2 }, expected: ["0", "2", "1"], ["0", "2", "1"],);
-    test_tuple!(order_12, t: { #[tabled(order = 2)] u8 #[tabled(order = 2)] u8 #[tabled(order = 2)] u8}, init: { 0 1 2 }, expected: ["0", "1", "2"], ["0", "1", "2"],);
-    test_tuple!(order_13, t: { #[tabled(order = 1)] u8 #[tabled(order = 1)] u8 #[tabled(order = 1)] u8}, init: { 0 1 2 }, expected: ["0", "2", "1"], ["0", "2", "1"],);
-    test_tuple!(order_14, t: { #[tabled(order = 2)] u8 #[tabled(order = 1)] u8 #[tabled(order = 0)] u8}, init: { 0 1 2 }, expected: ["2", "1", "0"], ["2", "1", "0"],);
-
-    test_tuple!(rename_all, t: #[tabled(rename_all = "UPPERCASE")] { u8 sstr}, init: { 0 "123" }, expected: ["0", "1"], ["0", "123"],);
-    test_tuple!(rename_all_field, t: { u8 #[tabled(rename_all = "UPPERCASE")] sstr}, init: { 0 "123" }, expected: ["0", "1"], ["0", "123"],);
-    test_tuple!(rename_all_field_with_rename_0, t: { u8 #[tabled(rename_all = "UPPERCASE", rename = "Something")] sstr}, init: { 0 "123" }, expected: ["0", "Something"], ["0", "123"],);
-    test_tuple!(rename_all_field_with_rename_1, t: { u8 #[tabled(rename = "Something")] #[tabled(rename_all = "UPPERCASE")] sstr}, init: { 0 "123" }, expected: ["0", "Something"], ["0", "123"],);
+    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,
-        t: { u8 #[tabled(display_with = "display_option")] Option<sstr> },
-        init: { 0 Some("v2") },
-        expected: ["0", "1"], ["0", "some v2"],
+        { { u8 #[tabled(display_with = "display_option")] Option<sstr> } },
+        { 0 Some("v2") },
+        { ["0", "1"], ["0", "some v2"] },
         pre: {
             fn display_option(o: &Option<sstr>) -> String {
                 match o {
@@ -168,9 +170,9 @@ mod tuple {
 
     test_tuple!(
         display_option_args,
-        t: { u8 #[tabled(display_with("display_option", 1, "234"))] Option<sstr> },
-        init: { 0 Some("v2") },
-        expected: ["0", "1"], ["0", "some 1 234"],
+        { { u8 #[tabled(display_with("display_option", 1, "234"))] Option<sstr> } },
+        { 0 Some("v2") },
+        { ["0", "1"], ["0", "some 1 234"] },
         pre: {
             fn display_option(val: usize, text: &str) -> String {
                 format!("some {val} {text}")
@@ -180,9 +182,9 @@ mod tuple {
 
     test_tuple!(
         display_option_self,
-        t: { u8 #[tabled(display_with = "Self::display_option")] Option<sstr> },
-        init: { 0 Some("v2") },
-        expected: ["0", "1"], ["0", "some v2"],
+        { { u8 #[tabled(display_with = "Self::display_option")] Option<sstr> } },
+        { 0 Some("v2") },
+        { ["0", "1"], ["0", "some v2"] },
         pre: {
             impl TestType {
                 fn display_option(o: &Option<sstr>) -> String {
@@ -197,9 +199,9 @@ mod tuple {
 
     test_tuple!(
         display_option_self_2,
-        t: { u8 #[tabled(display_with("Self::display_option", self))] Option<sstr> },
-        init: { 0 Some("v2") },
-        expected: ["0", "1"], ["0", "some v2"],
+        { { u8 #[tabled(display_with("Self::display_option", self))] Option<sstr> } },
+        { 0 Some("v2") },
+        { ["0", "1"], ["0", "some v2"] },
         pre: {
             impl TestType {
                 fn display_option(o: &TestType) -> String {
@@ -214,9 +216,9 @@ mod tuple {
 
     test_tuple!(
         display_option_self_3,
-        t: { u8 #[tabled(display_with("display_option", self))] Option<sstr> },
-        init: { 0 Some("v2") },
-        expected: ["0", "1"], ["0", "some v2"],
+        { { u8 #[tabled(display_with("display_option", self))] Option<sstr> } },
+        { 0 Some("v2") },
+        { ["0", "1"], ["0", "some v2"] },
         pre: {
             fn display_option(o: &TestType) -> String {
                 match o.1 {
@@ -228,35 +230,21 @@ mod tuple {
     );
 
     test_tuple!(
-        format_1,
-        t: { u8 #[tabled(format = "foo {}")] sstr },
-        init: { 0 "v2" },
-        expected: ["0", "1"], ["0", "foo v2"],
-    );
-
-    test_tuple!(
-        format_2,
-        t: { u8 #[tabled(format = "foo {:?}")] sstr },
-        init: { 0 "v2" },
-        expected: ["0", "1"], ["0", "foo \"v2\""],
+        display_option_self_4,
+        { { u8 #[tabled(display_with("display_option", self.0, self.0))] Option<sstr> } },
+        { 0 Some("v2") },
+        { ["0", "1"], ["0", "some 0.0"] },
+        pre: {
+            fn display_option(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]
-    fn format3() {
-        #[derive(Debug, Tabled)]
-        pub struct StructName(
-            u8,
-            #[allow(dead_code)]
-            #[tabled(format("foo {} {:?}", 2, self))]
-            String,
-        );
-
-        let value = StructName(0, String::from("string"));
-
-        assert_eq!(value.fields(), vec!["0", "foo 2 StructName(0, \"string\")"]);
-        assert_eq!(StructName::headers(), vec!["0", "1"]);
-    }
+    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() {
@@ -270,328 +258,466 @@ mod enum_ {
 
     test_enum!(
         basic,
-        t: { Security Embedded Frontend Unknown },
-        headers: ["Security", "Embedded", "Frontend", "Unknown"],
-        tests:
+        { { Security Embedded Frontend Unknown } },
+        {},
+        { ["Security", "Embedded", "Frontend", "Unknown"] },
+        {
             Security => ["+", "", "", ""],
             Embedded => ["", "+", "", ""],
             Frontend => ["", "", "+", ""],
-            Unknown => ["", "", "", "+"],
+            Unknown =>  ["", "", "", "+"],
+        }
     );
 
     test_enum!(
         diverse,
-        t: { A { a: u8, b: i32 } B(sstr) K },
-        headers: ["A", "B", "K"],
-        tests:
+        { { A { a: u8, b: i32 } B(sstr) K } },
+        {},
+        { ["A", "B", "K"] },
+        {
             A { a: 1, b: 2 } => ["+", "", ""],
             B("") => ["", "+",  ""],
             K => ["", "", "+"],
+        }
     );
 
     test_enum!(
         rename_variant,
-        t: { #[tabled(rename = "Variant 1")] A { a: u8, b: i32 } #[tabled(rename = "Variant 2")] B(sstr) K },
-        headers: ["Variant 1", "Variant 2", "K"],
-        tests:
+        { { #[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,
-        t: { A { a: u8, b: i32 } #[tabled(skip)] B(sstr) K },
-        headers: ["A", "K"],
-        tests:
+        { { A { a: u8, b: i32 } #[tabled(skip)] B(sstr) K } },
+        {},
+        { ["A", "K"] },
+        {
             A { a: 1, b: 2 } => ["+", ""],
             B("") => ["", ""],
             K => ["", "+"],
+        }
     );
 
     test_enum!(
         inline_variant,
-        t: {
+        {
+            {
             #[tabled(inline("Auto::"))] Auto { #[tabled(rename = "mod")] model: sstr, engine: sstr }
             #[tabled(inline)] Bikecycle( #[tabled(rename = "name")] sstr, #[tabled(inline)] Bike )
             Skateboard
+            }
         },
-        pre: {
+        {
             #[derive(Tabled)]
             struct Bike { brand: sstr, price: f32 }
-        }
-        headers: ["Auto::mod", "Auto::engine", "name", "brand", "price", "Skateboard"],
-        tests:
+        },
+        { ["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,
-        t: {
-            #[tabled(inline("backend::"))]
-            Backend { #[tabled(display_with = "display", rename = "name")] value: sstr }
-            Frontend
+        {
+            {
+                #[tabled(inline("backend::"))]
+                Backend {
+                    #[tabled(display_with = "display", rename = "name")]
+                    value: sstr
+                }
+                Frontend
+            }
         },
-        pre: {
+        {
             fn display(_: sstr) -> String {
                 "asd".to_string()
             }
-        }
-        headers: ["backend::name", "Frontend"],
-        tests:
+        },
+        { ["backend::name", "Frontend"] },
+        {
             Backend { value: "123" } => ["asd", ""],
             Frontend => ["", "+"],
+        }
     );
 
     test_enum!(
         inline_field_with_display_self_function,
-        t: {
-            #[tabled(inline("backend::"))]
-            Backend { #[tabled()] #[tabled(display_with("display", self), rename = "name")] value: sstr }
-            Frontend
+        {
+            {
+                #[tabled(inline("backend::"))]
+                Backend {
+                    #[tabled()]
+                    #[tabled(display_with("display", self), rename = "name")]
+                    value: sstr
+                }
+                Frontend
+            }
         },
-        pre: {
+        {
             fn display<T>(_: &T) -> String {
                 "asd".to_string()
             }
-        }
-        headers: ["backend::name", "Frontend"],
-        tests:
+        },
+        { ["backend::name", "Frontend"] },
+        {
             Backend { value: "123" } => ["asd", ""],
             Frontend => ["", "+"],
+        }
     );
 
     test_enum!(
         with_display,
-        t: {
-            #[tabled(inline)]
-            A(#[tabled(display_with = "format::<4>")] sstr)
-            B
+        {
+            {
+                #[tabled(inline)]
+                A(
+                    #[tabled(display_with = "format::<4>")]
+                    sstr
+                )
+                B
+            }
         },
-        pre: {
+        {
             fn format<const ID: usize>(_: sstr) -> String {
                 ID.to_string()
             }
-        }
-        headers: ["0", "B"],
-        tests:
+        },
+        { ["0", "B"] },
+        {
             A("") => ["4", ""],
             B => ["", "+"],
+        }
     );
 
     test_enum!(
         with_display_self,
-        t: {
-            #[tabled(inline)]
-            A(#[tabled(display_with("Self::format::<4>", self))] sstr)
-            B
+        {
+            {
+                #[tabled(inline)]
+                A(
+                    #[tabled(display_with("Self::format::<4>", self))]
+                    sstr
+                )
+                B
+            }
         },
-        pre: {
+        {
             impl TestType {
                 fn format<const ID: usize>(&self) -> String {
                     ID.to_string()
                 }
             }
+        },
+        { ["0", "B"] },
+        {
+            A("") => ["4", ""],
+            B => ["", "+"],
         }
-        headers: ["0", "B"],
-        tests:
+    );
+
+    test_enum!(
+        with_display_self_complex_0,
+        {
+            {
+                #[tabled(inline)]
+                A(
+                    #[tabled(display_with("Self::format::<4>", self, self.0))]
+                    sstr
+                )
+                B
+            }
+        },
+        {
+            impl TestType {
+                fn format<const ID: usize>(&self, _: sstr) -> String {
+                    ID.to_string()
+                }
+            }
+        },
+        { ["0", "B"] },
+        {
             A("") => ["4", ""],
             B => ["", "+"],
+        }
+    );
+
+    test_enum!(
+        with_display_self_complex_1,
+        {
+            {
+                #[tabled(inline)]
+                A{
+                    #[tabled(display_with("Self::format::<4>", self, self.asd))]
+                    asd: sstr
+                }
+                B
+            }
+        },
+        {
+            impl TestType {
+                fn format<const ID: usize>(&self, _: sstr) -> String {
+                    ID.to_string()
+                }
+            }
+        },
+        { ["asd", "B"] },
+        {
+            A { asd: "" } => ["4", ""],
+            B => ["", "+"],
+        }
     );
 
     test_enum!(
         rename_all_variant,
-        t: {
-            #[tabled(rename_all = "snake_case")]
-            VariantName1 { a: u8, b: i32 }
-            #[tabled(rename_all = "UPPERCASE")]
-            VariantName2(String)
-            K
+        {
+            {
+                #[tabled(rename_all = "snake_case")]
+                VariantName1 { a: u8, b: i32 }
+                #[tabled(rename_all = "UPPERCASE")]
+                VariantName2(String)
+                K
+            }
         },
-        headers: ["variant_name1", "VARIANTNAME2", "K"],
-        tests:
+        {},
+        { ["variant_name1", "VARIANTNAME2", "K"] },
+        {}
     );
 
     test_enum!(
         rename_all_enum,
-        t: #[tabled(rename_all = "snake_case")] {
-            VariantName1 { a: u8, b: i32 }
-            VariantName2(String)
-            K
+        {
+            #[tabled(rename_all = "snake_case")]
+            {
+                VariantName1 { a: u8, b: i32 }
+                VariantName2(String)
+                K
+            }
         },
-        headers: ["variant_name1", "variant_name2", "k"],
-        tests:
+        {},
+        { ["variant_name1", "variant_name2", "k"] },
+        {}
     );
 
     test_enum!(
         rename_all_enum_inherited_inside_struct_enum,
-        t: #[tabled(rename_all = "snake_case")] {
-            #[tabled(inline)]
-            VariantName1 { some_field_1: u8, some_field_2: i32 }
-            VariantName2(String)
-            K
+        {
+            #[tabled(rename_all = "snake_case")]
+            {
+                #[tabled(inline)]
+                VariantName1 { some_field_1: u8, some_field_2: i32 }
+                VariantName2(String)
+                K
+            }
         },
-        headers: ["some_field_1", "some_field_2", "variant_name2", "k"],
-        tests:
+        {},
+        { ["some_field_1", "some_field_2", "variant_name2", "k"] },
+        {}
     );
 
     test_enum!(
         rename_all_enum_inherited_inside_struct_override_by_rename_enum,
-        t: #[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
+        {
+            #[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
+            }
         },
-        headers: ["f1", "f2", "variant_name2", "k"],
-        tests:
+        {},
+        { ["f1", "f2", "variant_name2", "k"] },
+        {}
     );
 
     test_enum!(
         rename_all_enum_inherited_inside_struct_override_by_rename_all_enum,
-        t: #[tabled(rename_all = "snake_case")] {
-            #[tabled(inline)]
-            VariantName1 {
-                #[tabled(rename_all = "UPPERCASE")]
-                some_field_1: u8,
-                #[tabled(rename_all = "CamelCase")]
-                some_field_2: i32,
+        {
+            #[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
             }
-            VariantName2(String)
-            K
         },
-        headers: ["SOMEFIELD1", "someField2", "variant_name2", "k"],
-        tests:
+        {},
+        { ["SOMEFIELD1", "someField2", "variant_name2", "k"] },
+        {}
     );
 
     test_enum!(
         rename_all_variant_inherited_inside_struct_enum,
-        t: #[tabled(rename_all = "snake_case")] {
-            #[tabled(inline)]
+        {
             #[tabled(rename_all = "snake_case")]
-            VariantName1 {
-                some_field_1: u8,
-                some_field_2: i32,
+            {
+                #[tabled(inline)]
+                #[tabled(rename_all = "snake_case")]
+                VariantName1 {
+                    some_field_1: u8,
+                    some_field_2: i32,
+                }
+                VariantName2(String)
+                K
             }
-            VariantName2(String)
-            K
         },
-        headers: ["some_field_1", "some_field_2", "variant_name2", "k"],
-        tests:
+        {},
+        { ["some_field_1", "some_field_2", "variant_name2", "k"] },
+        {}
     );
 
     test_enum!(
         rename_all_variant_inherited_inside_struct_enum_overridden_by_rename,
-        t: #[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
+        {
+            #[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
+            }
         },
-        headers: ["f1", "f2", "variant_name2", "k"],
-        tests:
+        {},
+        { ["f1", "f2", "variant_name2", "k"] },
+        {}
     );
 
     test_enum!(
         rename_all_variant_inherited_inside_struct_override_by_rename_all_enum,
-        t: #[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,
+        {
+            #[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
             }
-            VariantName2(String)
-            K
         },
-        headers: ["SOMEFIELD1", "someField2", "variant_name2", "k"],
-        tests:
+        {},
+        { ["SOMEFIELD1", "someField2", "variant_name2", "k"] },
+        {}
     );
 
     test_enum!(
         inline_enum_as_whole,
-        t: #[tabled(inline)] {
-            AbsdEgh { a: u8, b: i32 }
-            B(String)
-            K
+        {
+            #[tabled(inline)] {
+                AbsdEgh { a: u8, b: i32 }
+                B(String)
+                K
+            }
         },
-        headers: ["TestType"],
-        tests:
+        {},
+        { ["TestType"] },
+        {
             AbsdEgh { a: 0, b: 0 }  => ["AbsdEgh"],
             B(String::new()) => ["B"],
             K => ["K"],
+        }
     );
 
     test_enum!(
         inline_enum_as_whole_and_rename,
-        t:
-        #[tabled(inline, rename_all = "snake_case")]
         {
-            AbsdEgh { a: u8, b: i32 }
-            B(String)
-            K
+            #[tabled(inline, rename_all = "snake_case")]
+            {
+                AbsdEgh { a: u8, b: i32 }
+                B(String)
+                K
+            }
         },
-        headers: ["TestType"],
-        tests:
+        {},
+        { ["TestType"] },
+        {
             AbsdEgh { a: 0, b: 0 }  => ["absd_egh"],
             B(String::new()) => ["b"],
             K => ["k"],
+        }
     );
 
     test_enum!(
         inline_enum_as_whole_and_rename_inner,
-        t: #[tabled(inline)] {
-            #[tabled(rename_all = "snake_case")]
-            AbsdEgh { a: u8, b: i32 }
-            #[tabled(rename_all = "lowercase")]
-            B(String)
-            K
+        {
+            #[tabled(inline)]
+            {
+                #[tabled(rename_all = "snake_case")]
+                AbsdEgh { a: u8, b: i32 }
+                #[tabled(rename_all = "lowercase")]
+                B(String)
+                K
+            }
         },
-        headers: ["TestType"],
-        tests:
+        {},
+        { ["TestType"] },
+        {
             AbsdEgh { a: 0, b: 0 }  => ["absd_egh"],
             B(String::new()) => ["b"],
             K => ["K"],
+        }
     );
 
     test_enum!(
         inline_enum_name,
-        t: #[tabled(inline("A struct name"))] {
-            AbsdEgh { a: u8, b: i32 }
-            B(String)
-            K
+        {
+            #[tabled(inline("A struct name"))]
+            {
+                AbsdEgh { a: u8, b: i32 }
+                B(String)
+                K
+            }
         },
-        headers: ["A struct name"],
-        tests:
+        {},
+        { ["A struct name"] },
+        {
             AbsdEgh { a: 0, b: 0 }  => ["AbsdEgh"],
             B(String::new()) => ["B"],
             K => ["K"],
+        }
     );
 
     test_enum!(
         enum_display_with_variant,
-        t: {
-            #[tabled(display_with = "display_variant1")]
-            AbsdEgh { a: u8, b: i32 }
-            #[tabled(display_with = "display_variant2::<200>")]
-            B(String)
-            #[tabled(display_with = "some::bar::display_variant1")]
-            K
+        {
+            {
+                #[tabled(display_with = "display_variant1")]
+                AbsdEgh { a: u8, b: i32 }
+                #[tabled(display_with = "display_variant2::<200>")]
+                B(String)
+                #[tabled(display_with = "some::bar::display_variant1")]
+                K
+            }
         },
-        pre: {
+        {
             fn display_variant1() -> &'static str {
                 "Hello World"
             }
@@ -607,25 +733,28 @@ mod enum_ {
                     }
                 }
             }
-        }
-        headers: ["AbsdEgh", "B", "K"],
-        tests:
+        },
+        { ["AbsdEgh", "B", "K"] },
+        {
             AbsdEgh { a: 0, b: 0 }  => ["Hello World", "", ""],
             B(String::new()) => ["", "asd 200", ""],
             K => ["", "", "Hello World 123"],
+        }
     );
 
     test_enum!(
         enum_display_with_self_variant,
-        t: {
-            #[tabled(display_with("display_variant1", self))]
-            AbsdEgh { a: u8, b: i32 }
-            #[tabled(display_with("display_variant2::<200, _>", self))]
-            B(String)
-            #[tabled(display_with("some::bar::display_variant1", self))]
-            K
+        {
+            {
+                #[tabled(display_with("display_variant1", self))]
+                AbsdEgh { a: u8, b: i32 }
+                #[tabled(display_with("display_variant2::<200, _>", self))]
+                B(String)
+                #[tabled(display_with("some::bar::display_variant1", self))]
+                K
+            }
         },
-        pre: {
+        {
             fn display_variant1<D>(_: &D) -> &'static str {
                 "Hello World"
             }
@@ -641,25 +770,28 @@ mod enum_ {
                     }
                 }
             }
-        }
-        headers: ["AbsdEgh", "B", "K"],
-        tests:
+        },
+        { ["AbsdEgh", "B", "K"] },
+        {
             AbsdEgh { a: 0, b: 0 }  => ["Hello World", "", ""],
             B(String::new()) => ["", "asd 200", ""],
             K => ["", "", "Hello World 123"],
+        }
     );
 
     test_enum!(
         enum_display_with_arguments,
-        t: {
-            #[tabled(display_with("display1", 1, 2, self))]
-            AbsdEgh { a: u8, b: i32 }
-            #[tabled(display_with("display2::<200>", "Hello World"))]
-            B(String)
-            #[tabled(display_with("display1", 100, 200, self))]
-            K
+        {
+            {
+                #[tabled(display_with("display1", 1, 2, self))]
+                AbsdEgh { a: u8, b: i32 }
+                #[tabled(display_with("display2::<200>", "Hello World"))]
+                B(String)
+                #[tabled(display_with("display1", 100, 200, self))]
+                K
+            }
         },
-        pre: {
+        {
             fn display1<D>(val: usize, val2: usize, _: &D) -> String {
                 format!("{val} {val2}")
             }
@@ -667,55 +799,106 @@ mod enum_ {
             fn display2<const VAL: usize>(val: &str) -> String {
                 format!("asd {VAL} {val}")
             }
-        }
-        headers: ["AbsdEgh", "B", "K"],
-        tests:
+        },
+        { ["AbsdEgh", "B", "K"] },
+        {
             AbsdEgh { a: 0, b: 0 }  => ["1 2", "", ""],
             B(String::new()) => ["", "asd 200 Hello World", ""],
             K => ["", "", "100 200"],
+        }
     );
 
-    test_enum!(order_0, t: { #[tabled(order = 0)] V1(u8) V2(u8) V3(u8) }, headers: ["V1", "V2", "V3"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],);
-    test_enum!(order_1, t: { #[tabled(order = 1)] V1(u8) V2(u8) V3(u8) }, headers: ["V2", "V1", "V3"], tests: V1(0) => ["", "+", ""], V2(0) => ["+", "", ""], V3(0) => ["", "", "+"],);
-    test_enum!(order_2, t: { #[tabled(order = 2)] V1(u8) V2(u8) V3(u8) }, headers: ["V2", "V3", "V1"], tests: V1(0) => ["", "", "+"], V2(0) => ["+", "", ""], V3(0) => ["", "+", ""],);
-    test_enum!(order_3, t: { V1(u8) #[tabled(order = 0)] V2(u8) V3(u8) }, headers: ["V2", "V1", "V3"], tests: V1(0) => ["", "+", ""], V2(0) => ["+", "", ""], V3(0) => ["", "", "+"],);
-    test_enum!(order_4, t: { V1(u8) #[tabled(order = 1)] V2(u8) V3(u8) }, headers: ["V1", "V2", "V3"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],);
-    test_enum!(order_5, t: { V1(u8) #[tabled(order = 2)] V2(u8) V3(u8) }, headers: ["V1", "V3", "V2"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],);
-    test_enum!(order_6, t: { V1(u8) V2(u8) #[tabled(order = 0)] V3(u8) }, headers: ["V3", "V1", "V2"], tests: V1(0) => ["", "+", ""], V2(0) => ["", "", "+"], V3(0) => ["+", "", ""],);
-    test_enum!(order_7, t: { V1(u8) V2(u8) #[tabled(order = 1)] V3(u8) }, headers: ["V1", "V3", "V2"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],);
-    test_enum!(order_8, t: { V1(u8) V2(u8) #[tabled(order = 2)] V3(u8) }, headers: ["V1", "V2", "V3"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],);
-    test_enum!(order_9, t: { #[tabled(order = 2)] V1(u8) V2(u8) #[tabled(order = 0)] V3(u8) }, headers: ["V3", "V2", "V1"], tests: V1(0) => ["", "", "+"], V2(0) => ["", "+", ""], V3(0) => ["+", "", ""],);
-    test_enum!(order_10, t: { #[tabled(order = 2)] V1(u8) V2(u8) #[tabled(order = 1)] V3(u8) }, headers: ["V2", "V3", "V1"], tests: V1(0) => ["", "", "+"], V2(0) => ["+", "", ""], V3(0) => ["", "+", ""],);
-    test_enum!(order_11, t: { #[tabled(order = 2)] V1(u8) #[tabled(order = 2)] V2(u8) #[tabled(order = 1)] V3(u8) }, headers: ["V1", "V3", "V2"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],);
-    test_enum!(order_12, t: { #[tabled(order = 2)] V1(u8) #[tabled(order = 1)] V2(u8) #[tabled(order = 0)] V3(u8) }, headers: ["V3", "V2", "V1"], tests: V1(0) => ["", "", "+"], V2(0) => ["", "+", ""], V3(0) => ["+", "", ""],);
-    test_enum!(order_13, t: { #[tabled(order = 0)] V1(u8) #[tabled(order = 0)] V2(u8) #[tabled(order = 0)] V3(u8) }, headers: ["V3", "V1", "V2"], tests: V1(0) => ["", "+", ""], V2(0) => ["", "", "+"], V3(0) => ["+", "", ""],);
-    test_enum!(order_14, t: { #[tabled(order = 1)] V1(u8) #[tabled(order = 1)] V2(u8) #[tabled(order = 1)] V3(u8) }, headers: ["V1", "V3", "V2"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "", "+"], V3(0) => ["", "+", ""],);
-    test_enum!(order_15, t: { #[tabled(order = 2)] V1(u8) #[tabled(order = 2)] V2(u8) #[tabled(order = 2)] V3(u8) }, headers: ["V1", "V2", "V3"], tests: V1(0) => ["+", "", ""], V2(0) => ["", "+", ""], V3(0) => ["", "", "+"],);
-
-    test_enum!(order_0_inlined, t: #[tabled(inline)] { #[tabled(order = 1)] V1(u8) V2(u8) V3(u8) }, headers: ["TestType"], tests: V1(0) => ["V1"], V2(0) => ["V2"], V3(0) => ["V3"],);
+    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,
-        t: {
-            #[tabled(inline)]
-            AbsdEgh {
-                #[tabled(format("{}-{}", self.a, self.b))]
-                a: u8,
-                b: i32
+        {
+            {
+                #[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
             }
-            #[tabled(format("{} s", 4))]
-            B(String)
-            #[tabled(inline)]
-            C(#[tabled(rename = "C", format("{} ss", 4))] String)
-            #[tabled(format = "k.")]
-            K
         },
-        headers: ["a", "b", "B", "C", "K"],
-        tests:
+        {},
+        { ["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."],
+        }
     );
 }
 
@@ -737,51 +920,130 @@ mod unit {
 mod structure {
     use super::*;
 
-    test_struct!(empty, t: { } init: { } expected: [], []);
-    test_struct!(general, t: { f1: u8, f2: sstr } init: { f1: 0, f2: "v2" } expected: ["f1", "f2"], ["0", "v2"]);
-    test_struct!(rename, t: { #[tabled(rename = "field 1")] f1: u8, #[tabled(rename = "field 2")] f2: sstr } init: { f1: 0, f2: "v2" } expected: ["field 1", "field 2"], ["0", "v2"]);
-    test_struct!(skip, t: { #[tabled(skip)] f1: u8, #[tabled(rename = "field 2", skip)] f2: sstr, f3: sstr } init: { f1: 0, f2: "v2", f3: "123" } expected: ["f3"], ["123"]);
-    test_struct!(skip_true, t: { #[tabled(skip = true)] f1: u8, #[tabled(rename = "field 2", skip = true)] f2: sstr, f3: sstr } init: { f1: 0, f2: "v2", f3: "123" } expected: ["f3"], ["123"]);
+    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,
-        t: {
-            #[tabled(inline = true)]
-            id: u8,
-            name: sstr,
-            #[tabled(inline)]
-            ed: Education
+        {
+            {
+                #[tabled(inline = true)]
+                id: u8,
+                name: sstr,
+                #[tabled(inline)]
+                ed: Education
+            }
         }
-        pre: {
+        {
             #[derive(Tabled)]
             struct Education { uni: sstr, graduated: bool }
         }
-        init: { id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }}
-        expected: ["u8", "name","uni","graduated"], ["0", "Maxim", "BNTU", "true"]
+        {
+            id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }
+        }
+        {
+            ["u8", "name","uni","graduated"],
+            ["0", "Maxim", "BNTU", "true"]
+        }
     );
     test_struct!(
         inline_with_prefix,
-        t: {
-            #[tabled(rename = "it's an ignored option", inline)]
-            id: u8,
-            name: sstr,
-            #[tabled(inline("education::"))]
-            ed: Education,
+        {
+            {
+                #[tabled(rename = "it's an ignored option", inline)]
+                id: u8,
+                name: sstr,
+                #[tabled(inline("education::"))]
+                ed: Education,
+            }
         }
-        pre: {
+        {
             #[derive(Tabled)]
             struct Education { uni: sstr, graduated: bool }
         }
-        init: { id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }}
-        expected: ["u8", "name","education::uni","education::graduated"], ["0", "Maxim", "BNTU", "true"]
+        {
+            id: 0, name: "Maxim", ed: Education { uni: "BNTU", graduated: true }}
+        {
+            ["u8", "name","education::uni","education::graduated"],
+            ["0", "Maxim", "BNTU", "true"]
+        }
     );
     test_struct!(
         display_with,
-        t: {
-            f1: u8,
-            #[tabled(display_with = "display_option")]
-            f2: Option<sstr>,
+        {
+            {
+                f1: u8,
+                #[tabled(display_with = "display_option")]
+                f2: Option<sstr>,
+            }
         }
-        pre: {
+        {
             fn display_option(o: &Option<sstr>) -> String {
                 match o {
                     Some(s) => format!("some {s}"),
@@ -789,47 +1051,53 @@ mod structure {
                 }
             }
         }
-        init: { f1: 0, f2: Some("v2") }
-        expected: ["f1", "f2"], ["0", "some v2"]
+        { f1: 0, f2: Some("v2") }
+        { ["f1", "f2"], ["0", "some v2"] }
     );
     test_struct!(
         display_with_args,
-        t: {
-            f1: u8,
-            #[tabled(display_with("display_option", 1, 2, 3))]
-            f2: Option<sstr>,
+        {
+            {
+                f1: u8,
+                #[tabled(display_with("display_option", 1, 2, 3))]
+                f2: Option<sstr>,
+            }
         }
-        pre: {
+        {
             fn display_option(v1: usize, v2: usize, v3: usize) -> String {
                 format!("{v1} {v2} {v3}")
             }
         }
-        init: { f1: 0, f2: Some("v2") }
-        expected: ["f1", "f2"], ["0", "1 2 3"]
+        { f1: 0, f2: Some("v2") }
+        { ["f1", "f2"], ["0", "1 2 3"] }
     );
     test_struct!(
         display_with_args_using_self,
-        t: {
-            f1: u8,
-            #[tabled(display_with("display_option", self.f1, 2, 3))]
-            f2: Option<sstr>,
+        {
+            {
+                f1: u8,
+                #[tabled(display_with("display_option", &self.f1, 2, 3))]
+                f2: Option<sstr>,
+            }
         }
-        pre: {
+        {
             fn display_option(v1: &u8, v2: usize, v3: usize) -> String {
                 format!("{v1} {v2} {v3}")
             }
         }
-        init: { f1: 0, f2: Some("v2") }
-        expected: ["f1", "f2"], ["0", "0 2 3"]
+        { f1: 0, f2: Some("v2") }
+        { ["f1", "f2"], ["0", "0 2 3"] }
     );
     test_struct!(
         display_with_self_static_method,
-        t: {
-            f1: u8,
-            #[tabled(display_with = "Self::display_option")]
-            f2: Option<sstr>,
+        {
+            {
+                f1: u8,
+                #[tabled(display_with = "Self::display_option")]
+                f2: Option<sstr>,
+            }
         }
-        pre: {
+        {
             impl TestType {
                 fn display_option(o: &Option<sstr>) -> String {
                     match o {
@@ -839,17 +1107,19 @@ mod structure {
                 }
             }
         }
-        init: { f1: 0, f2: Some("v2") }
-        expected: ["f1", "f2"], ["0", "some v2"]
+        { f1: 0, f2: Some("v2") }
+        { ["f1", "f2"], ["0", "some v2"] }
     );
     test_struct!(
         display_with_self_static_method_2,
-        t: {
-            f1: u8,
-            #[tabled(display_with("Self::display_option", self))]
-            f2: Option<sstr>,
+        {
+            {
+                f1: u8,
+                #[tabled(display_with("Self::display_option", self))]
+                f2: Option<sstr>,
+            }
         }
-        pre: {
+        {
             impl TestType {
                 fn display_option(o: &TestType) -> String {
                     match o.f2 {
@@ -859,17 +1129,19 @@ mod structure {
                 }
             }
         }
-        init: { f1: 0, f2: Some("v2") }
-        expected: ["f1", "f2"], ["0", "some v2"]
+        { f1: 0, f2: Some("v2") }
+        { ["f1", "f2"], ["0", "some v2"] }
     );
     test_struct!(
         display_with_self_2_self_static_method_2,
-        t: {
-            f1: u8,
-            #[tabled(display_with("Self::display_option", self))]
-            f2: Option<sstr>,
+        {
+            {
+                f1: u8,
+                #[tabled(display_with("Self::display_option", self))]
+                f2: Option<sstr>,
+            }
         }
-        pre: {
+        {
             impl TestType {
                 fn display_option(&self) -> String {
                     match self.f2 {
@@ -879,17 +1151,19 @@ mod structure {
                 }
             }
         }
-        init: { f1: 0, f2: Some("v2") }
-        expected: ["f1", "f2"], ["0", "some v2"]
+        { f1: 0, f2: Some("v2") }
+        { ["f1", "f2"], ["0", "some v2"] }
     );
     test_struct!(
         display_with_self_2_self_static_method,
-        t: {
-            f1: u8,
-            #[tabled(display_with("display_option", self))]
-            f2: Option<sstr>,
+        {
+            {
+                f1: u8,
+                #[tabled(display_with("display_option", self))]
+                f2: Option<sstr>,
+            }
         }
-        pre: {
+        {
             fn display_option(o: &TestType) -> String {
                 match o.f2 {
                     Some(s) => format!("some {s}"),
@@ -897,74 +1171,104 @@ mod structure {
                 }
             }
         }
-        init: { f1: 0, f2: Some("v2") }
-        expected: ["f1", "f2"], ["0", "some v2"]
+        { f1: 0, f2: Some("v2") }
+        { ["f1", "f2"], ["0", "some v2"] }
     );
-    test_struct!(order_0, t: { #[tabled(order = 0)] f0: u8, f1: u8, f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f0", "f1", "f2"], ["0", "1", "2"]);
-    test_struct!(order_1, t: { #[tabled(order = 1)] f0: u8, f1: u8, f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f1", "f0", "f2"], ["1", "0", "2"]);
-    test_struct!(order_2, t: { #[tabled(order = 2)] f0: u8, f1: u8, f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f1", "f2", "f0"], ["1", "2", "0"]);
-    test_struct!(order_3, t: { f0: u8, #[tabled(order = 0)] f1: u8, f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f1", "f0", "f2"], ["1", "0", "2"]);
-    test_struct!(order_4, t: { f0: u8, #[tabled(order = 1)] f1: u8, f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f0", "f1", "f2"], ["0", "1", "2"]);
-    test_struct!(order_5, t: { f0: u8, #[tabled(order = 2)] f1: u8, f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f0", "f2", "f1"], ["0", "2", "1"]);
-    test_struct!(order_6, t: { f0: u8, f1: u8, #[tabled(order = 0)] f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f2", "f0", "f1"], ["2", "0", "1"]);
-    test_struct!(order_7, t: { f0: u8, f1: u8, #[tabled(order = 1)] f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f0", "f2", "f1"], ["0", "2", "1"]);
-    test_struct!(order_8, t: { f0: u8, f1: u8, #[tabled(order = 2)] f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f0", "f1", "f2"], ["0", "1", "2"]);
-    test_struct!(order_9, t: { #[tabled(order = 2)] f0: u8, f1: u8, #[tabled(order = 0)] f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f2", "f1", "f0"], ["2", "1", "0"]);
-    test_struct!(order_10, t: { #[tabled(order = 2)] f0: u8, #[tabled(order = 1)] f1: u8, f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f2", "f1", "f0"], ["2", "1", "0"]);
-    test_struct!(order_11, t: { #[tabled(order = 2)] f0: u8, #[tabled(order = 2)] f1: u8, #[tabled(order = 1)] f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f0", "f2", "f1"], ["0", "2", "1"]);
-    test_struct!(order_12, t: { #[tabled(order = 2)] f0: u8, #[tabled(order = 1)] f1: u8, #[tabled(order = 0)] f2: u8 } init: { f0: 0, f1: 1, f2: 2 } expected: ["f2", "f1", "f0"], ["2", "1", "0"]);
+    test_struct!(
+        display_with_args_using_self_array_and_func,
+        {
+            {
+                #[tabled(skip)]
+                f1: [u8; 4],
+                #[tabled(display_with("display_option", &[self.f1[0], self.f1[1]], ToString::to_string(&self.f3.to_string())))]
+                f2: Option<sstr>,
+                f3: usize,
+            }
+        }
+        {
+            fn display_option(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,
-        t: #[tabled(rename_all = "UPPERCASE")] { f1: u8, f2: sstr }
-        init: { f1: 0, f2: "v2" }
-        expected: ["F1", "F2"], ["0", "v2"]
+        { #[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,
-        t: #[tabled(rename_all = "UPPERCASE")] { #[tabled(rename = "213213")] f1: u8, f2: sstr }
-        init: { f1: 0, f2: "v2" }
-        expected: ["213213", "F2"], ["0", "v2"]
+        { #[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,
-        t: #[tabled(rename_all = "UPPERCASE")] { #[tabled(rename_all = "lowercase")] f1: u8, f2: sstr }
-        init: { f1: 0, f2: "v2" }
-        expected: ["f1", "F2"], ["0", "v2"]
+        { #[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,
-        t: { #[tabled(rename_all = "lowercase")] f1: u8, #[tabled(rename_all = "UPPERCASE")] f2: sstr }
-        init: { f1: 0, f2: "v2" }
-        expected: ["f1", "F2"], ["0", "v2"]
+        { { #[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,
-        t: { #[tabled(rename_all = "lowercase", rename = "Hello")] f1: u8, #[tabled(rename_all = "UPPERCASE")] f2: sstr }
-        init: { f1: 0, f2: "v2" }
-        expected: ["Hello", "F2"], ["0", "v2"]
+        { { #[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,
-        t: {
-            #[tabled(format = "{} cc")]
-            f1: u8,
-            f2: u8,
+        {
+            {
+                #[tabled(format = "{} cc")]
+                f1: u8,
+                f2: u8,
+            }
         }
-        init: { f1: 0, f2: 0 }
-        expected: ["f1", "f2"], ["0 cc", "0"]
+        {}
+        { f1: 0, f2: 0 }
+        { ["f1", "f2"], ["0 cc", "0"] }
     );
 
     test_struct!(
         format_with_args,
-        t: {
-            #[tabled(format("{}/{} cc/kg", self.f1, self.f2))]
-            f1: u8,
-            f2: u8,
+        {
+            {
+                #[tabled(format("{}/{} cc/kg", self.f1, self.f2))]
+                f1: u8,
+                f2: u8,
+            }
         }
-        init: { f1: 1, f2: 2 }
-        expected: ["f1", "f2"], ["1/2 cc/kg", "2"]
+        {}
+        { f1: 1, f2: 2 }
+        { ["f1", "f2"], ["1/2 cc/kg", "2"] }
     );
 
     // #[test]
@@ -979,12 +1283,12 @@ mod structure {
     // }
 }
 
-test_tuple!(skipped_fields_not_implement_display_tuple, t: { #[tabled(skip)] () sstr }, init: { () "123" }, expected: ["1"], ["123"],);
-test_struct!(skipped_fields_not_implement_display_struct, t: { #[tabled(skip)] _unit: (), s: sstr } init: { _unit: (), s: "123" } expected: ["s"], ["123"],);
+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,
-    t: { s: sstr, #[tabled(inline)] f: S1 }
-    pre: {
+    { { s: sstr, #[tabled(inline)] f: S1 } }
+    {
         #[derive(Tabled)]
         struct S1 {
             #[tabled(skip)]
@@ -992,76 +1296,83 @@ test_struct!(
             s: sstr,
         }
     }
-    init: { s: "123", f: S1 { _unit: (), s: "..." } }
-    expected: ["s", "s"], ["123", "..."],
+    { s: "123", f: S1 { _unit: (), s: "..." } }
+    { ["s", "s"], ["123", "..."] },
 );
 test_enum!(
     skipped_fields_not_implement_display_enum,
-    t: {
-        #[tabled(inline("A::"))]
-        A {
-            name: sstr
-        }
-        #[tabled(inline("B::"))]
-        B {
-            issue: usize,
-            name: sstr,
-            #[tabled(skip)]
-            _gem: (),
+    {
+        {
+            #[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
         }
-        #[tabled(inline("C::"))]
-        C(usize, #[tabled(skip)] (), sstr)
-        D
     },
-    headers: ["A::name", "B::issue", "B::name", "C::0", "C::2", "D"],
-    tests:
+    {},
+    { ["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 => ["", "", "", "", "", "+"],
+    }
 );
 
 test_struct!(
     ignore_display_with_when_used_with_inline,
-    t: { f1: sstr, f2: sstr, #[tabled(display_with = "print", inline)] f3: usize }
-    init: { f1: "123", f2: "456", f3: 789 }
-    expected: ["f1", "f2", "usize"], ["123", "456", "789"],
+    { { f1: sstr, f2: sstr, #[tabled(display_with = "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,
-    t: { f1: sstr, f2: sstr, #[tabled(display_with = "print", )] #[tabled(inline)] f3: usize }
-    init: { f1: "123", f2: "456", f3: 789 }
-    expected: ["f1", "f2", "usize"], ["123", "456", "789"],
+    { { f1: sstr, f2: sstr, #[tabled(display_with = "print", )] #[tabled(inline)] f3: usize } }
+    {}
+    { f1: "123", f2: "456", f3: 789 }
+    { ["f1", "f2", "usize"], ["123", "456", "789"], }
 );
 test_struct!(
     display_with_and_rename,
-    t: { f1: sstr, f2: sstr, #[tabled(display_with = "print", rename = "asd")] f3: usize }
-    pre: { #[allow(dead_code)] fn print<T>(_: T) -> String { String::new() } }
-    init: { f1: "123", f2: "456", f3: 789 }
-    expected: ["f1", "f2", "asd"], ["123", "456", ""],
+    { { f1: sstr, f2: sstr, #[tabled(display_with = "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,
-    t: { f1: sstr, f2: sstr, #[tabled(display_with = "print")] #[tabled(rename = "asd")] f3: usize }
-    pre: { #[allow(dead_code)] fn print<T>(_: T) -> String { String::new() } }
-    init: { f1: "123", f2: "456", f3: 789 }
-    expected: ["f1", "f2", "asd"], ["123", "456", ""],
+    { { f1: sstr, f2: sstr, #[tabled(display_with = "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,
-    t: { f1: sstr, f2: sstr, #[tabled(display_with = "print", rename_all = "UPPERCASE")] f3: usize }
-    pre: { #[allow(dead_code)] fn print<T>(_: T) -> String { String::new() } }
-    init: { f1: "123", f2: "456", f3: 789 }
-    expected: ["f1", "f2", "F3"], ["123", "456", ""],
+    { { f1: sstr, f2: sstr, #[tabled(display_with = "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)]
-            pub struct $name {
+            struct $name {
                 field: usize,
             }
         };
@@ -1217,12 +1528,41 @@ fn test_reimport_trait_by_crate_attribute() {
 #[test]
 fn test_display_with_2() {
     #[derive(tabled::Tabled)]
-    pub struct Struct<'a> {
+    #[allow(dead_code)]
+    struct Struct<'a> {
         #[tabled(display_with("std::path::Path::display"))]
         path: &'a std::path::Path,
     }
 }
 
+#[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(), ["", "", "", "+"]);
+}
+
 mod __ {
     #[test]
     fn dont_import_the_trait() {